教义2多个mappedBy?
Posted
技术标签:
【中文标题】教义2多个mappedBy?【英文标题】:Doctrine 2 multiple mappedBy? 【发布时间】:2015-09-25 21:44:14 【问题描述】:我在正确设置 Doctrine 映射时遇到问题。
我有一个CashRegister
实体,它有一个垃圾箱位置和一个回收箱位置。两个位置都来自同一类型(BinLocation
Entity)。
从CashRegister
、CashRegister->getBinLocations()
和CashRegister->getReturnBinLocations()
传出工作正常,但我怎样才能实现BinLocation->getCashRegisters()
返回所有CashRegister
引用的实体(binLocation
+ returnBinLocation
)?
/**
* CashRegister
*
* @ORM\Table(name="cash_registers")
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class CashRegister
...
/**
* @var BinLocation
*
* @ORM\ManyToOne(targetEntity="BinLocation", inversedBy="cashRegisters")
* @ORM\JoinColumn(name="bin_location_id", referencedColumnName="id")
*/
private $binLocation;
/**
* @var BinLocation
*
* @ORM\ManyToOne(targetEntity="BinLocation", inversedBy="cashRegisters")
* @ORM\JoinColumn(name="return_bin_location_id", referencedColumnName="id")
*/
private $returnBinLocation;
/**
* @return BinLocation
*/
public function getBinLocation()
return $this->binLocation;
/**
* @return BinLocation
*/
public function getReturnBinLocation()
return $this->returnBinLocation;
...
/**
* BinLocation
*
* @ORM\Table(name="bin_locations")
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class BinLocation
...
/**
* @var CashRegister[]
*
* @ORM\OneToMany(targetEntity="CashRegister", mappedBy="binLocation") <= Here is the problem, in this case mappedBy need to be an array [binLocation, returnBinLocation]
*/
private $cashRegisters;
/**
* @return CashRegister[]
*/
public function getCashRegisters()
return $this->cashRegisters;
...
【问题讨论】:
【参考方案1】:我还搜索了解决方案并为 Doctrine 制作了一个补丁,以便您可以将 custom_attributes 链接到各种实体类型。
教义 2.6:https://github.com/danielbeeke/doctrine2/commit/2d8530176b872cb490c5c88b8c8e17d8d0091388 教义 2.7:https://github.com/danielbeeke/doctrine2/commit/5bde696848ea9fe7035fadc4d46baa4c0d51f3a2
/**
* @Entity
* @Table(name="product")
* @HasLifecycleCallbacks
**/
class Product
/**
* One Product has Many Attributes.
*
* @OneToMany(
* targetEntity="CustomAttribute",
* mappedBy="EntityId",
* mappedByType=
* "field": "EntityType",
* "value": "product"
*
* )
*
* @var $CustomAttributes ArrayCollection
*/
protected $CustomAttributes;
/**
* @Entity
* @Table(name="custom_attribute")
* @HasLifecycleCallbacks
**/
class CustomAttribute_entity
/** @Id @Column(type="integer") @GeneratedValue */
protected $Id;
/**
* Many Attributes have One Entity of the EntityType provided.
* @ManyToOne(targetEntity="Product", inversedBy="CustomAttributes")
* @JoinColumn(name="EntityId", referencedColumnName="Id")
*/
protected $EntityId;
/** @Column(type="string") */
protected $EntityType;
/** @Column(type="string") */
protected $Type;
/** @Column(type="string") */
protected $Value;
【讨论】:
【参考方案2】:简单的答案是你不能。 mappedBy
只接受一个参数。
实现您想要的解决方案非常简单。在BinLocation
中创建第二个属性,名为:cashRegisters2
,如下所示:
/**
* @var CashRegister[]
*
* @ORM\OneToMany(targetEntity="CashRegister", mappedBy="binLocation")
*/
private $cashRegisters;
/**
* @var CashRegister[]
*
* @ORM\OneToMany(targetEntity="CashRegister", mappedBy="binLocation")
*/
private $cashRegisters2;
然后在 getCashRegisters
方法中合并集合。
/**
* @return CashRegister[]
*/
public function getCashRegisters()
return new ArrayCollection(
array_merge($cashRegisters->toArray(), $cashRegisters2->toArray())
);
同时相应地更改您的 CashRegister
映射:
/**
* @var BinLocation
*
* @ORM\ManyToOne(targetEntity="BinLocation", inversedBy="cashRegisters")
* @ORM\JoinColumn(name="bin_location_id", referencedColumnName="id")
*/
private $binLocation;
/**
* @var BinLocation
*
* @ORM\ManyToOne(targetEntity="BinLocation", inversedBy="cashRegisters2")
* @ORM\JoinColumn(name="return_bin_location_id", referencedColumnName="id")
*/
private $returnBinLocation;
注意:我没有测试代码。此示例仅供服务器参考。
注意 2: ArrayCollection 合并的灵感来自这里:https://***.com/a/16871539/2853903
【讨论】:
感谢 Mark 的回答,但这个解决方案看起来有点像 hack。在谷歌搜索了一段时间后(在我写这个问题之前),我注意到只有少数人有同样的问题。是否有可能以更(企业)“教条”的方式实现它的另一种方法? (类,表,一切都可以更改,唯一的要求是我可以将 bin 位置和返回 bin 位置存储到收银机并正确取回) 问题出在不能指定多个mappedBy
字段。因此,您需要使用 Doctrine 为您提供的其他功能来解决问题,上面提供了一个示例。如果您想要核心 Doctrine 功能更改,可以尝试在 Github 上请求它们?但是在这个阶段,您将获得的所有解决方案都将是“hacky”:)以上是关于教义2多个mappedBy?的主要内容,如果未能解决你的问题,请参考以下文章