在 Doctrine 中将一对多映射到 "joined" 子 class 时,如何消除模式验证错误?
How do I get rid of schema validation errors when mapping one-to-many to a "joined" child class in Doctrine?
我有一个抽象 ContentItem
class,它是一个具有继承类型 JOINED
的 Doctrine 实体。它与 BusinessAccount
实体处于多对一关系。 BusinessAccount
与 ContentItem
的非抽象子 class 具有一对多关系,特别是 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
个子 class 属于一个 BusinessAccount
,同时将不同的子分离到 BusinessAccount
上的单独 replationships边.
这段代码工作得很好,但是它没有通过 Doctrine 的 doctrine:schema:validate
命令的模式验证:
Mapping
[FAIL] The entity-class App\Application\BusinessAccount mapping is invalid:
- The field App\Application\BusinessAccount#textItems is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity App\Entity\TextItem#businessAccount does not contain the required 'inversedBy="textItems"' attribute.
在我看来,Doctrine 正确地将 many-to-one
和 one-to-many
识别为一个关联的两个方面,但它希望我在 [= 上明确指定反向 属性 的名称25=]。我不能这样做,因为有多个逆属性,每个子 class of ContentItem
.
我可以通过将 $businessAccount
属性 移动到 ContentItem
的子 class 来消除这些错误。我不觉得这个解决方案令人满意,因为它引入了代码重复,很难保证每个 ContentItem
子类型的所有权并将外键移动到其他表。
我试图用指定的 inversedBy
覆盖子 class 中的 $businessAccount
属性,但这并没有使错误消失。
是否有一个干净的解决方案可以让我解决这些错误?
我想你可以用 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
}
我有一个抽象 ContentItem
class,它是一个具有继承类型 JOINED
的 Doctrine 实体。它与 BusinessAccount
实体处于多对一关系。 BusinessAccount
与 ContentItem
的非抽象子 class 具有一对多关系,特别是 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
个子 class 属于一个 BusinessAccount
,同时将不同的子分离到 BusinessAccount
上的单独 replationships边.
这段代码工作得很好,但是它没有通过 Doctrine 的 doctrine:schema:validate
命令的模式验证:
Mapping
[FAIL] The entity-class App\Application\BusinessAccount mapping is invalid:
- The field App\Application\BusinessAccount#textItems is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity App\Entity\TextItem#businessAccount does not contain the required 'inversedBy="textItems"' attribute.
在我看来,Doctrine 正确地将 many-to-one
和 one-to-many
识别为一个关联的两个方面,但它希望我在 [= 上明确指定反向 属性 的名称25=]。我不能这样做,因为有多个逆属性,每个子 class of ContentItem
.
我可以通过将 $businessAccount
属性 移动到 ContentItem
的子 class 来消除这些错误。我不觉得这个解决方案令人满意,因为它引入了代码重复,很难保证每个 ContentItem
子类型的所有权并将外键移动到其他表。
我试图用指定的 inversedBy
覆盖子 class 中的 $businessAccount
属性,但这并没有使错误消失。
是否有一个干净的解决方案可以让我解决这些错误?
我想你可以用 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
}