web-dev-qa-db-ja.com

Doctrine "関係を通じて新しいエンティティが見つかりました"エラー

まず最初に、この質問を投稿する前に、すべてのドキュメントを読み、これをたくさんグーグルで検索したと言いたいです。私はそのエラーが何を意味するのか知っています(関係の永続化されていないエンティティ)

私はそれを取得するべきではないと思うところにこのエラーが発生しています。

私はOneToMany Bi-Directionalの関係を次のように持っています:

Class Channel
{
    /** 
    * @ORM\OneToMany(targetEntity="Step", mappedBy="channel", cascade={"all"}, orphanRemoval=true)
    * @ORM\OrderBy({"sequence" = "ASC"})
    */
    protected $steps;
}

Class Step
{
    /** 
    * @ORM\ManyToOne(targetEntity="Channel", inversedBy="steps")
    */
    protected $channel;
}

1つのChannelは多くのStepを持つことができ、所有側はChannelです。 Doctrine 2.4から2.5にアップグレードした後、次のエラーが発生します:

Doctrine\ORM\ORMInvalidArgumentException:エンティティの永続化操作をカスケードするように構成されていない関係 'Company\MyBundle\Entity\Step#channel'を通じて新しいエンティティが見つかりました

なぜ逆側から新しい関係を見つけるのですか?これが私のコードです:

$channel = new Channel();
$step = new Step();
$channel->addStep($step);
$em->persist($channel);
$em->flush();

ありがとう!

10
Reza S

あなたは正しいです:Doctrineは所有側への変更のみを探しますが、あなたは間違っています:あなたの関係の所有側はStepではなくChannelです。

なぜステップは所有側なのですか?なぜなら、外部キーを持つエンティティだからです。 Doctrineドキュメントはあなたに言います

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

可能な解決策:

  • cascade={"all"}をStepエンティティに入れてカスケード操作を反転させてみてください(all正しい選択ですか?)

  • 両方のエンティティを明示的に永続化します。

    $channel = new Channel();
    $step = new Step();
    $channel->addStep($step);
    $em->persist($channel);
    $em->persist($step);
    $em->flush();
    

    ここ ここで提供されている2番目の方法でも問題がない理由を読むことができます

9
DonCallisto

あなたは固執しようとします$channelですが、内部にStepエンティティがあります。したがって、Doctrineには、挿入のためにキューに入れられる2つのエンティティがあります。次にDoctrine最初がStepである順序でエンティティを並べ替えます。 channel_id外部キー(現在は空です)。 Doctrineこのエンティティを永続化してみて、それがchannel_idは空であり、永続化するためのカスケードルールを確認します。カスケードルールは表示されず、この例外がスローされます。

1