この問題は、1)複合キーを持つ結合テーブル、2)フォームコンポーネント、3)結合テーブルがフォームコンポーネントの 'コレクション'フィールドによって作成されているエンティティである場合には一意ではないようです。私は多くの人が問題を抱えていたが、解決策はそれほど多くなかったので、私は私のことを分かち合うと思った。
2つの外部キーのインスタンスが1つだけデータベースに残るようにしたいので、私は複合プライマリキーを保持したかったのです。私はOrderItem
のコレクションフィールドを持っていた形でOrder
オブジェクトを構築した場合の例
/** @Entity */
class Order
{
/** @OneToMany(targetEntity="OrderItem", mappedBy="order") */
private $items;
public function __construct(Customer $customer)
{
$this->items = new Doctrine\Common\Collections\ArrayCollection();
}
}
/** @Entity */
class Product
{
/** @OneToMany(targetEntity="OrderItem", mappedBy="product") */
private $orders;
.....
public function __construct(Customer $customer)
{
$this->orders = new Doctrine\Common\Collections\ArrayCollection();
}
}
/** @Entity */
class OrderItem
{
/** @Id @ManyToOne(targetEntity="Order") */
private $order;
/** @Id @ManyToOne(targetEntity="Product") */
private $product;
/** @Column(type="integer") */
private $amount = 1;
}
として、私が直面した問題を this entity setupを使用して、私はせずに、エンティティをOrderItemに保存することができないであろうDoctrine EntityManagerは、OrderItem属性を持つOrderオブジェクトを保存することができませんでした(それは、それらをまとめて保存することを主張しているためです) 。カスケードをオフにすることはできません。関連するエンティティを保存していないと不平を言います。Order
を保存する前に、関連するエンティティを保存することはできません。どのような謎。 私の解決策は、関連付けられたエンティティを削除し、Order
を保存してから、関連付けられたエンティティをOrderオブジェクトに再導入して、再度を保存することでした。だから、最初の私は、ArrayCollectionの属性$items
class Order
{
.....
public function setItemsArray(Doctrine\Common\Collections\ArrayCollection $itemsArray = null){
if(null){
$this->items->clear();
}else{
$this->items = $itemsArray;
}
....
}
の質量割り当て機能を作成し、その後、私のコントローラで私が注文するためのフォームを処理する場所。
//get entity manager
$em = $this->getDoctrine()->getManager();
//get order information (with items)
$order = $form->getData();
//pull out items array from order
$items = $order->getItems();
//clear the items from the order
$order->setItemsArray(null);
//persist and flush the Order object
$em->persist($order);
$em->flush();
//reintroduce the order items to the order object
$order->setItemsArray($items);
//persist and flush the Order object again):
$em->persist($order);
$em->flush();
それはあなたが(もっとここPersist object with two foreign identities in doctrineを参照)を2回を持続し、フラッシュする必要があることを吸います。しかし、それはあなたのための教えであり、力のすべてがあれば、あなたを束縛することができます。しかし、うまくいけば、オブジェクトはすでにデータベースに入っているので、編集ではなく新しいオブジェクトを作成するときにのみ、これを行う必要があります。
出典
2015-05-20 21:53:29
JTG
あなたは正しいです、私は同時に注文と連絡先の関係を追加しようとしています。私は前に注文を洗い流そうとしましたが、次に 'カスケード= {" persist "}"の必要性についてエラーを受け取り、それを元に戻すと最初に関係を保存しようとします。あなたはどこかの実例を持っていますか?私は1つを見つけることができません... – cheesemacfly
あなたは手動で関係を維持する必要があります。すべての 'cascade = {" persist "}'は、そのセットとの関係を持つエンティティを永続化すると自動的に '$ em-> persist($ relationshipObject)'を追加します。オフにし、手動で関係オブジェクトを永続化し、2回目のフラッシュを実行します。 –
しかし、 'cascade = {" persist "}'を削除して、orderオブジェクトを最初に永続/フラッシュすると、 'TEST \ MyBundle \ Entity \ Orders#relations 'という関係で新しいエンティティが見つかりました。エンティティ:TEST \ MyBundle \ Entity \ Relations ... 'の永続操作をカスケードするように構成されていなかったものです。リレーションオブジェクトに 'detach()'を使用しようとしましたが、成功しませんでした... – cheesemacfly