2

理由はわかりません。基本的なロジックが欠けている可能性がありますが、常に同じ問題に遭遇します。ManyToMany コレクションを永続化することはできません。また、OneToMany コレクションにも直面していますが、それを回避することはできます。

私はドクトリンのドキュメントを読んで、mappedBy と inversedBy のことを理解していると思います (最後のものは常に所有者であり、そのためデータを永続化する責任があります。間違っている場合は修正してください)。

ここに私が今持っている基本的な例がありますが、私には理解できません。

私はSiteと呼ばれるエンティティを持っています:

#Site.php
...
/**
 * @ORM\ManyToMany(targetEntity="Category", mappedBy="sites")
 */
protected $categories;

そして別のものはCategoryと呼ばれます:

#Category.php
...
/**
 * @ORM\ManyToMany(targetEntity="Site", inversedBy="categories")
 * @ORM\JoinTable(name="sites_categories")
 */
protected $sites;

Symfony2 エンティティ ジェネレーターを使用して、次のようにいくつかのゲッターとセッターをエンティティに追加しました。

サイト:

#Site.php
...
/**
 * Add categories
 *
 * @param My\MyBundle\Entity\Category $categories
 */
public function addCategory(\My\MyBundle\Entity\Category $categories)
{
    $this->categories[] = $categories;
}

/**
 * Get categories
 *
 * @return Doctrine\Common\Collections\Collection 
 */
public function getCategories()
{
    return $this->categories;
}

同じことが

カテゴリ:

#Category.php
...
/**
 * Add sites
 *
 * @param My\MyBundle\Entity\Site $sites
 */
public function addSite(\My\MyBundle\Entity\Site $sites)
{
    $this->sites[] = $sites;
}

/**
 * Get sites
 *
 * @return Doctrine\Common\Collections\Collection 
 */
public function getSites()
{
    return $this->sites;
}

けっこうだ。

今私のコントローラーで、私は Site オブジェクトを永続化しようとしています:

public function newsiteAction() {

    $site = new Site();
    $form = $this->createFormBuilder($site); // generated with the FormBuilder, so the form includes Category Entity

    // ... some more logic, like if(POST), bindRequest() etc.

        if ($form->isValid()) {
            $em = $this->getDoctrine()
            ->getEntityManager();
            $em->persist($site);
            $em->flush();
        }
}

結果は常に同じです。Site オブジェクトは保持されますが、Category エンティティは保持されません。そして、私もその理由を知っています (私はそう思います): Category エンティティが所有側であるためです。

しかし、私はそれを持続させるために常にこのようなことをしなければなりませんか? (実際には、これは一部の OneToMany コレクションに対する私の回避策です)

$categories = $form->get('categories')->getData();
foreach($categories as $category) {
    // persist etc.
}

しかし、削除、編集などのために上記と同じループを実行する必要があるなど、ここで多くの問題に直面しています。

ヒントはありますか?そんな私の気持ちを晴らしてくれる人には本当にサイバーハグします。ありがとう!

. . .

アップデート

ManyToMany マッピング間の関係 (所有側と逆側) を変更することになりました。

他の誰かがその問題に遭遇した場合は、双方向関係の概念について明確にする必要があります。これは、私も理解するのに時間がかかりました (そして、今理解できたことを願っています。このリンクを参照してください)。基本的に私の質問に答えたのは次のとおりです。永続化するオブジェクトは常に所有サイトでなければなりません(所有サイトは常に、注釈で「反転」したエンティティです)。

また、カスケード アノテーションの概念もあります ( moonwave99のおかげで、このリンクを参照してください) 。

ありがとう、将来の参考のために誰かを助けることを願っています! :)

4

1 に答える 1

2

関係に関して、カスケードアノテーションOneToManyについて知りたい- Doctrine docs [8.6] から:

次のカスケード オプションがあります。

  • persist : 関連付けられたエンティティに永続化操作をカスケードします。
  • remove : 関連付けられたエンティティに削除操作をカスケードします。
  • merge : マージ操作を関連付けられたエンティティにカスケードします。
  • detach : デタッチ操作を関連付けられたエンティティにカスケードします。
  • all : 関連付けられたエンティティへの操作の永続化、削除、マージ、およびデタッチをカスケードします。

次のドキュメントの例:

<?php
class User
{
    //...
    /**
     * Bidirectional - One-To-Many (INVERSE SIDE)
     *
     * @OneToMany(targetEntity="Comment", mappedBy="author", cascade={"persist", "remove"})
     */
    private $commentsAuthored;
    //...
}

作成者にコメントを追加すると、保存しても保持されます。作成者を削除すると、コメントも別れを告げます。

最近、REST サービスをセットアップするときに同じ問題が発生しましたが、カスケード アノテーションにより、以前に言及したすべての回避策を取り除くことができました [最初に使用したもの] - これがお役に立てば幸いです。

于 2012-08-29T23:16:00.903 に答える