2

Storyエンティティにタグを追加しようとしています。textextを利用するために独自のバンドル、フォームタイプ、データトランスフォーマーを作成しましたが、すべてうまく機能していると思いました...しかし、これは既存のストーリーにタグを追加する場合にのみ当てはまります。ストーリーの作成と同時にタグを追加しようとすると、結合テーブルにレコードを2回作成しようとしているために例外がスローされ、主キーの重複エラーが発生します。

リクエストをフォームにバインドした後、永続化する前にコントローラーにデバッグしたため、カスタムフォームタイプとデータトランスフォーマーに問題があるとは思いません。ここのすべては完全に問題ないようです。ストーリーエンティティにはタグIのみが含まれています。追加しましたが、重複はありません。

役立つ場合に備えて、tags属性の構成は次のとおりです。

/**
 * @ORM\ManyToMany(targetEntity="Tag")
 * @ORM\JoinTable(name="story__story_tags",
 *   joinColumns={@ORM\JoinColumn(name="story_id", referencedColumnName="id")},
 *   inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")}
 * )
 */
protected $tags;

これが私のログ出力からの抜粋です:

INSERT INTO stories (created_at, updated_at, published_at, author_id, media_id, title, short_title, summary, text, slug, active, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ({"1":{"date":"2012-09-11 15:07:20","timezone_type":3,"timezone":"Europe\/London"},"2":{"date":"2012-09-11 15:07:20","timezone_type":3,"timezone":"Europe\/London"},"3":{"date":"2012-09-11 14:56:00","timezone_type":3,"timezone":"Europe\/London"},"4":10,"5":68,"6":"Story with tags","7":"","8":"Test","9":"<p>test<\/p>","10":"story-with-tags","11":true,"12":"media"})
INSERT INTO story__media (id, story_media_id, media_size, show_caption) VALUES (?, ?, ?, ?) ({"1":"130","2":null,"3":"0","4":false})
SELECT s0_.slug AS slug0 FROM stories s0_ LEFT JOIN story__gallery s1_ ON s0_.id = s1_.id LEFT JOIN story__media s2_ ON s0_.id = s2_.id LEFT JOIN story__competition s3_ ON s0_.id = s3_.id WHERE s0_.slug LIKE 'story-with-tags-872875%' AND s0_.id <> ? ([130])
INSERT INTO story__counters (story_id, hits, shares, comments, updated_at) VALUES (?, ?, ?, ?, ?) ({"1":130,"2":0,"3":0,"4":0,"5":{"date":"2012-09-11 15:07:20","timezone_type":3,"timezone":"Europe\/London"}})
INSERT INTO story__sections (story_id, section_id, section_position) VALUES (?, ?, ?) ({"1":130,"2":212,"3":1})
UPDATE stories SET slug = ?, updated_at = ? WHERE id = ? (["story-with-tags-872875",{"date":"2012-09-11 15:07:20","timezone_type":3,"timezone":"Europe\/London"},130])
website/story/130 (DELETE) 11.00 ms
website/story/130 (PUT) 5.12 ms
Context: { title: 'Story with tags', summary: Test, text: '<p>test</p>', author: billy-wiggins, publishedAt: 1347371760, tags: [test] }
INSERT INTO story__story_tags (story_id, tag_id) VALUES (?, ?) ([130,9])
INSERT INTO story__story_tags (story_id, tag_id) VALUES (?, ?) ([130,9])

3行目から最後の行までわかるように、私のエンティティはelasticsearchにインデックス付けされており、「test」というタグが1つだけ含まれています。これに続いて、タグ#9をストーリー#130に関連付けようとしている2つの重複クエリを確認できます。なぜこれが起こっているのか誰かが知っていますか?

INSERT IGNORE少なくとも問題を回避するので、どういうわけかこれらの挿入クエリに構文を使用させることは可能ですか?

ありがとう!

4

3 に答える 3

0

さて、臭いハックを使用してこの問題を「修正」する方法を見つけることができました。他に方法がない限り、これを正しい答えとして受け入れる可能性は低いので、これを修正する良い方法を知っている場合は返信してください.

Story エンティティとタグを同時に作成する場合にのみ問題が発生するためcreate、基本の Admin クラスのメソッドを次のように拡張しました: (鼻をかむ準備をしてください...今すぐ!)

/**
 * TODO achieve this in a non-smelly way
 * 
 * @param Story $object
 * @return mixed|void
 */
public function create($object)
{
    // Create fails when story has tags, so remove them...
    $tags = $object->getTags();
    $object->setTags(new \Doctrine\Common\Collections\ArrayCollection());
    parent::create($object);

    // ...then add them again and update.
    $object->setTags($tags);
    $this->getModelManager()->update($object);
}

きっともっときちんとした解決策があるに違いない?

于 2012-09-11T15:33:34.917 に答える
0

これを __construct() に置きます:

$this->Tags = new \Doctrine\Common\Collections\ArrayCollection() ;

1 対 2 多および多 2 多のすべての関係に対して、これを行う必要があります。

于 2012-09-12T09:20:53.373 に答える
0

この解決策はうまくいきます:

public function __construct()
{
    $this->tags = new ArrayCollection();
}

public function addTag(Tag $tag)
{
    if (!this->tags->contains($tag)) {
        $this->tags->add($tag);
    }
}

重複キーは次回追加されません

于 2015-11-15T12:57:38.577 に答える