2016-05-14 7 views
1

私は非常に単純です(私は考えました!)、私はInvoiceエンティティとクーポンエンティティを持っています。請求書には多数のクーポンを適用することができます。逆にクーポンは多くの請求書で使用できます。Doctrine ManyToMany Relationship

除くゲッター/セッター:

請求書

namespace Application\Entity; 

use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Entity 
* @ORM\Table(name="invoices") 
*/ 
class Invoice 
    /** 
    * @ORM\ManyToMany(targetEntity="Application\Entity\Coupon") 
    * @ORM\JoinTable(name="invoices_coupons") 
    */ 
    protected $coupons; 

    public function addCoupon(Coupon $coupon){ 
     if(!$this->coupons) 
      $this->coupons = new ArrayCollection(); 

     $this->coupons->add($coupon); 
    } 
} 

クーポン私は予想通り、スキーマを生成するためのヘルパーツールを実行すると

/** 
* @ORM\Entity 
* @ORM\Table(name="coupons", indexes={@ORM\Index(name="code_idx", columns={"code"})}) 
*/ 
class Coupon implements CandidateInterface 
{ 
    /** 
    * @var \Ramsey\Uuid\Uuid 
    * 
    * @ORM\Id 
    * @ORM\Column(type="uuid") 
    * @ORM\GeneratedValue(strategy="CUSTOM") 
    * @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator") 
    */ 
    protected $id; 

    /** 
    * @var string 
    * @ORM\Column(type="string", length=32, unique=true) 
    */ 
    protected $code; 

} 

は、それが作成されますcoupon_id、invoice_id(完璧)を含むinvoices_couponsテーブルを結合します。

コードには、既存の保存済み請求書と同様の既存のクーポンがあります。

は私が行うことができないようだ。私はこのエラーを取得

// runs a QB to return the coupon, returns a Coupon Entity 
$coupon = $couponMapper->getActiveByCode('SAVEBIG'); 
$invoice->addCoupon($coupon); 
$invoiceMapper->getEntityManager()->update($invoice); 
$invoiceMapper->getEntityManager()->flush(); 

:今

A new entity was found through the relationship \Application\Entity\Invoice#coupons that was not configured to cascade persist operations for entity: (coupon toString). To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={\u0022persist\u0022}).

を、私はこれは新しいクーポンを作成する必要はありません。何故これを試しているのですか?クーポンは既に存在し、ERからロードされ、既存のエンティティに追加されています。

エラーメッセージに記載されていることを行うと、新しいクーポンをクーポン表に複製しようとします。

ご意見ありがとうございます。

+0

なぜマージですか? 2つのマッパーが同じエンティティマネージャを共有していますか? – Cerad

+0

私は、ドキュメントを読んでマージにつまずいた。代わりにupdateを使用すると、この種のエラーが発生します。エンティティ:HOST5の永続操作をカスケードするように構成されていない、新しいエンティティが\\ Entity \\ Invoice#coupons \ u0027の関係で見つかりました。この問題を解決するには、この未知のエンティティのEntityManager#persist()を明示的に呼び出すか、カスケードを設定すると、この関連付けが@ManyToOne(..、cascade = {\ u0022persist \ u0022})などのマッピングに保持されます。 "、 ' – Saeven

答えて

2

Doctrine\ORM\EntityManager::update()は存在しないようです。 addCoupon()呼び出しとflush()呼び出しの間に何もする必要はありません。

コードを簡略化しても魔法のように修正されない場合は、次の手順は$couponMapper->getEntityManager() === $invoiceMapper->getEntityManager()を確認することです。

これらのマッパークラスをどのようにインスタンス化するのかは不明ですが、各EntityManagerがエンティティ用に独自の内部アイデンティティマップを保持していることを理解することが重要です。したがって、何らかの理由でDICが2つの異なるEM(各Mapperに1つ)をインスタンス化している場合、$ invoiceMapperのEMは$ couponを管理対象として認識しません。

これが当てはまるのは奇妙なことです。 ZF2のServiceManagerを使用していると仮定すると、EntityMangerサービスを明示的に共有しないように設定する必要があります。

しかし、何とか2つの異なるEntityManagerを持つことは、あなたが提供したコードを考えると、私が考えることができる最も明白なことです。

+0

誰かが共有していない、なぜこれが行われたのかを掘り下げるために!A + – Saeven

関連する問題