在Doctrine 2中如何设置可以拥有自己收藏的集合?

时间:2013-05-22 13:53:08

标签: doctrine-orm zend-framework2

我使用zf2并且我有实体DepositDict,它可以有许多periodTimeAmounts。每个periodTimeAmount都可以有许多periodMoney元素。我可以使用许多periodTimeAmounts保存到DB我的实体,但是仅为最后一个periodTimemount实体保存periodMoney。

DepositDict

<?php
/*...*/

class DepositDict
{
/*...*/

/**
 *
 * @ORM\OneToMany(targetEntity="DepositDict\Entity\DepositDictPeriodTimeAmount", mappedBy="depositDict", cascade={"persist", "remove"})
 * @var \Doctrine\Common\Collections\ArrayCollection
 */
protected $periodTimeAmounts;


public function __construct() {
    $this->periodTimeAmounts = new ArrayCollection();
}

/*...*/

public function getPeriodTimeAmounts()
{
    return $this->periodTimeAmounts;
}

public function addPeriodTimeAmounts(Collection $periodTimeAmounts)
{
    if ( $this->getPeriodType() == self::PERIOD_TYPE_TIME_AMOUNT ) {

        foreach ( $periodTimeAmounts as $periodTimeAmount )
        {
            $periodTimeAmount->setDepositDict($this);
            $this->periodTimeAmounts->add($periodTimeAmount);
        }
    }
}

public function removePeriodTimeAmounts(Collection $periodTimeAmounts)
{
    foreach ( $periodTimeAmounts as $periodTimeAmount )
    {
        $periodTimeAmount->setDepositDict(null);
        $this->periodTimeAmounts->removeElement($periodTimeAmount);
    }
}

}
?>

DepositDictPeriodTimeAmount

<?php
/*...*/

class DepositDictPeriodTimeAmount
{

/*...*/

/**
 * @ORM\ManyToOne(targetEntity="DepositDict\Entity\DepositDict", inversedBy="periodTimeAmounts")
 * @ORM\JoinColumn(name="deposit_dict_id", referencedColumnName="id")
 */
protected $depositDict;

/**
 * @ORM\OneToMany(targetEntity="DepositDict\Entity\DepositDictPeriodMoney", mappedBy="periodTimeAmount", cascade={"persist", "remove"})
 */
protected $periodMoney;


public function __construct() {
    $this->periodMoney = new ArrayCollection();
}

public function getDepositDict()
{
    return $this->depositDict;
}

public function setDepositDict(DepositDict $depositDict=null)
{
    if ( $depositDict === null || $depositDict instanceof DepositDict ) {
        $this->depositDict = $depositDict;
    }
    else {
        throw new \InvalidArgumentException('$depositDict must be instance of Entity\DepositDict');
    }
}

public function getPeriodMoney()
{
    return $this->periodMoney;
}

public function addPeriodMoney(Collection $moneyPeriods) //changed name because money is uncountable
{
    foreach ( $moneyPeriods as $moneyPeriod )
    {
        $moneyPeriod->setPeriodTimeAmount($this);
        $this->periodMoney->add($moneyPeriod);
    }
}

public function removePeriodMoney(Collection $moneyPeriods)
{
    foreach ( $moneyPeriods as $moneyPeriod )
    {
        $moneyPeriod->setPeriodTimeAmount(null);
        $this->periodMoney->removeElement($moneyPeriod);
    }
}

/*...*/

}
?>

DepositDictPeriodMoney

<?php
/*...*/

class DepositDictPeriodMoney
{
/*...*/


/**
 * @ORM\ManyToOne(targetEntity="DepositDict\Entity\DepositDictPeriodTimeAmount", inversedBy="periodMoney")
 * @ORM\JoinColumn(name="deposit_dict_period_time_amount_id", referencedColumnName="id")
 */
protected $periodTimeAmount;

/*...*/

public function getPeriodTimeAmount()
{
    return $this->periodTimeAmount;
}

public function setPeriodTimeAmount(DepositDictPeriodTimeAmount $periodTimeAmount=null)
{
    if ( $periodTimeAmount === null || $periodTimeAmount instanceof DepositDictPeriodTimeAmount ) {
        $this->periodTimeAmount = $periodTimeAmount;
    }
    else {
        throw new \InvalidArgumentException('$periodTimeAmount must be instance of Entity\DepositDictPeriodTimeAmount');
    }
}

}
?>

缺少什么?

1 个答案:

答案 0 :(得分:0)

重要

Doctrine只会检查关联的拥有方是否有变化。

忽略仅对关联的反面进行的更改。确保更新双向关联的两面(或至少从Doctrine的角度更新所有方)

  • OneToMany协会永远不是拥有方。
  • 反面必须使用OneToOne,OneToMany或ManyToMany映射声明的mappedBy属性。 mappedBy属性包含拥有方的关联字段的名称
  • 拥有方必须使用OneToOne,ManyToOne或ManyToMany映射声明的inversedBy属性。 inversedBy属性包含反面的关联字段的名称。
  • ManyToOne始终是双向关联的拥有方。
  • OneToMany始终是双向关联的反面。

集合中的新实体不会由学说自动管理。

首先请确保在冲洗之前调用persist。

$em->persist($entity); 
$em->flush();

您已经设置了级联持久删除选项 - 这很好。

您要尝试的下一件事是将合并选项添加到您的级联中。 如果您的相关实体是针对某些共振的,那么它们将被合并,例如:

/**
 * @ORM\OneToMany(targetEntity="DepositDict\Entity\DepositDictPeriodMoney", mappedBy="periodTimeAmount",   cascade={"persist", "remove", "merge"})
 */

merge:Cascades将操作合并到关联实体。