10

私はこのコードを持っています

// ONE to many Bidir -- inverse side
    /**
     * @ORM\OneToMany(targetEntity="Item", mappedBy="Room", cascade={"persist"})
     **/
    protected $items;

反対側

// ONE to many Bidir-- own side
    /**
     * @ORM\ManyToOne(targetEntity="Room", inversedBy="items")
     * @ORM\JoinColumn(name="room_id", referencedColumnName="id")
     **/
    protected $room;

私の問題は、アイテム ページに移動して Room を選択すると、Room ページで事前に選択されたアイテムが表示されることです。

しかし、部屋のページに移動して多くのアイテムを複数選択しようとすると、それらは保持されません

編集: OneToMany リレーションシップでのみ発生していることを確認しました。多対多の場合、正常に機能しています

EDIT2:

複数のアイテムを選択できるフォームと選択ボックスがあるバックエンド領域について話しています。このフォーム/CRUD コード/コントローラーは教義によって生成されます。だから私は余分な機能を追加する必要はありません。いずれにせよ、これは私のコントローラーコードです

$editForm   = $this->createForm(new RoomType(), $entity);


        $request = $this->getRequest();

        $editForm->bindRequest($request);
        if ($editForm->isValid()) {
            $em->persist($entity);
            $em->flush();

このようなコントローラーでウォークスルーしようとすると

foreach($entity->getItems() as $item)
        echo $item;

それから私はそこにあなたのすべてのアイテムを見ることができます。したがって、すべてのアイテムがメイン オブジェクトにありますが、永続化されていないことを意味します。どうしてか分かりません。

未払いがある場合は、裏側に問題があります。どうすれば関係を逆と逆から所有に変えることができますか

4

2 に答える 2

10

注釈のコメントに基づいて、コードが間違っています。

属性を指定するため、これは所有側です。inversedBy

/**
 * ONE to many Bidir-- Inverse side
 * @ORM\ManyToOne(targetEntity="Room", inversedBy="items")
 * @ORM\JoinColumn(name="room_id", referencedColumnName="id")
 **/
protected $room;

これは逆側です(mappedBy属性があるため):

/**
 * ONE to many Bidir -- owning side
 * @ORM\OneToMany(targetEntity="Item", mappedBy="Room", cascade={"persist"})
 **/
protected $items;

したがって、あなたのコードは次のように言っています:Itemは所有側でRoomあり、逆側です。

双方向のリレーションシップの所有側は、OneToOne、ManyToOne、または ManyToMany マッピング宣言の inversedBy 属性を使用て、逆側を参照する必要があります。inversedBy 属性は、関係の逆側であるエンティティ内のフィールドを指定します。

よりきれいにするには:

所有側は、OneToOne、ManyToOne、または ManyToMany マッピング宣言の inversedBy 属性を使用する必要があります。inversedBy 属性には、逆側の関連付けフィールドの名前が含まれています。

一方、逆側の場合:

双方向リレーションシップの反対側は、OneToOne、OneToMany、または ManyToMany マッピング宣言のmappedBy 属性を使用して、その所有側を参照する必要があります。MappedBy 属性は、関係の所有者であるエンティティ内のフィールドを指定します。

そしてまた:

逆側では、OneToOne、OneToMany、または ManyToMany マッピング宣言の mappingBy 属性を使用する必要があります。MappedBy 属性には、所有側の関連付けフィールドの名前が含まれています。

さらに、もう 1 つの重要な考慮事項:

ManyToOne は、常に双方向関連の所有側です。

OneToMany は常に双方向関連の逆側です

したがって、反対側 (部屋) からアイテムを永続化するには、どのアイテムが選択/選択解除されたか、およびルームにそのアイテムが既に含まれているかどうかを確認する必要があります。

于 2012-08-17T09:21:10.400 に答える
3

ループを使用して部屋を設定するだけです。アイテムは側を負っていて、あなたは逆側 (部屋) を編集しています。symfony2 は、逆のものを編集している間、負の側を更新しません。

最も簡単な解決策は、部屋を永続化する前にループを使用することです。

foreach($entity->getItems() as $item){
    $item->setRoom($room);
}

そして逆側にカスケードします:

/**
 * @ORM\OneToMany(targetEntity="Item", mappedBy="Room", cascade={"persist"})
 **/
protected $items;

私のプロジェクトでは、コレクション イベント リスナーに基づいて再利用可能なソリューションを作成しました。時間とスキルがあれば、同じことをすることをお勧めします

于 2012-08-21T12:59:34.010 に答える