我有一个抽象的ContentItem
类,它是具有继承类型JOINED
的Doctrine实体。它与BusinessAccount
实体处于多对一关系。 BusinessAccount
与ContentItem
的非抽象子类(尤其是TextItem
)具有一对多的关系,这些子类与上述多对一的关系相反。
这里是代码:(删除了不相关的部分)
/**
* @ORM\Entity
* @ORM\InheritanceType("JOINED")
*/
abstract class ContentItem
{
/**
* @var BusinessAccount
* @ORM\ManyToOne(targetEntity=BusinessAccount::class)
*/
protected $businessAccount;
}
/*
* @ORM\Entity
*/
class BusinessAccount
{
/**
* @var Collection<TextItem>
* @ORM\OneToMany(targetEntity=TextItem::class, mappedBy="businessAccount")
*/
private $textItems;
}
/*
* @ORM\Entity
*/
class TextItem extends ContentItem
{
// nothing interesting here
}
想法是确保每个ContentItem
子类都属于BusinessAccount
,同时在BusinessAccount
侧将不同的子代分成单独的复制词。
此代码工作得很好,但是它没有通过Doctrine的doctrine:schema:validate
命令通过模式验证:
映射
[[FAIL]实体类App \ Application \ BusinessAccount映射无效:
- 字段App \ Application \ BusinessAccount#textItems位于双向关系的相反侧,但是目标实体App \ Entity \ TextItem#businessAccount上指定的mappingBy关联不包含必需的'inversedBy =“ textItems “'属性。
[在我看来,Doctrine正确地将many-to-one
和one-to-many
标识为一个关联的两侧,但是它希望我在ContentItem::$businessAccount
上明确指定逆属性的名称。我无法执行此操作,因为有多个逆属性,每个ContentItem
的子类一个。
我可以通过将$businessAccount
属性移到ContentItem
的子类中来消除这些错误。我发现此解决方案并不令人满意,因为它引入了代码重复,使得难以保证每个ContentItem
子类型的所有权并将外键移至其他表。
我已尝试在指定了$businessAccount
的子类中重写inversedBy
属性,但它不会使错误消失。
是否有一个干净的解决方案可以让我解决这些错误?
我认为您可以使用Association Overrides来做到这一点。
基本上,您在父实体中将具有正确且完整的映射(例如,包含inversed_by
属性:]
/**
* @ORM\Entity
* @ORM\InheritanceType("JOINED")
*/
abstract class ContentItem
{
/**
* @var BusinessAccount
* @ORM\ManyToOne(targetEntity=BusinessAccount::class, inversedBy="textItems")
*/
protected $businessAccount;
}
然后在需要时在子级中定义特定的替代:
/*
* @ORM\Entity
* @ORM\AssociationOverrides({
* @ORM\AssociationOverride(name="businessAccount",
* inversedBy="otherProperty"
* )
* })
*/
class TextItem extends ContentItem
{
// nothing interesting here
}