1

私は zf2 を使用しており、多くの periodTimeAmounts を持つことができるエンティティ DepositDict があります。各 periodTimeAmount には、多くの periodMoney 要素を含めることができます。多くの periodTimeAmounts を持つエンティティを DB に保存できますが、 periodMoney は最後の periodTimeAmount エンティティに対してのみ保存されます。

預金通帳

<?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');
    }
}

}
?>

何が欠けていますか?

4

1 に答える 1

1

重要

Doctrine は関連付けの所有側の変更のみをチェックします。

関連の逆側のみに加えられた変更は無視されます。双方向の関連付けの両側 (または、Doctrine の観点からは、少なくとも所有側) を更新してください。

  • OneToMany アソシエーションが所有側になることはありません。
  • 逆側では、OneToOne、OneToMany、または ManyToMany マッピング宣言の mappingBy 属性を使用する必要があります。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 : マージ操作を関連付けられたエンティティにカスケードします。

于 2013-05-23T05:27:03.483 に答える