web-dev-qa-db-ja.com

Doctrine多対1の関係の持続操作

ストーリーテーブルとユーザーテーブルがあります。ストーリーテーブルの列useridは、userテーブルのIDを参照する外部キーです。

私は、ユーザーがストーリーテーブルに格納されている多くのストーリーを持っている可能性があるという関係を設定しました。両方のテーブルのエンティティを作成しました。

ただし、操作をストーリーテーブルのみに永続化しようとすると、新しいユーザーエントリの詳細が要求されます。

私の目的は、既存のuserIdを使用して新しいストーリーを追加することです。

ここにエラーを投稿しています:

エンティティの永続的な操作をカスケードするように構成されていない関係 'Story#_userId'を介して新しいエンティティが見つかりました:User @ 0000000038960c50000000008ea93852。この問題を解決するには:この不明なエンティティでEntityManager#persist()を明示的に呼び出すか、@ ManyToOne(..、cascade = {\ "persist \"})などのマッピングでこの関連付けをカスケード持続するように構成します。

ManyToOne関係をStoryエンティティに設定しました:

/**
 * @ManyToOne(targetEntity="User", inversedBy = "_story" )
 * @JoinColumns({
 *     @JoinColumn(name="user_id", referencedColumnName="id")
 * })
 */

private $_userId;  

データベーススキーマを確認したところ、関係が正しく設定されています。だから私はストーリー挿入プロセスを行いました。

$user = new User();
$user->setUserId($id);
$story = new Story();
$story->setContent("....");
$story->setUserid($user);
$this->em->persist($story);
$this->em->flush();
18
sbi

おそらく、ストーリーエンティティを永続化していますが、ユーザーは永続化していません。このようなものがあれば:

$story = new Story();
$user = new User();
$story->setUser($user);
$em->persist($story);
$em->flush();

1つのエンティティを永続化しているため、これにより致命的なエラーが発生しますが、その関係を通じて、Doctrineは別の新しいエンティティを検索します。2つのオプションがあります。

両方のエンティティで永続化を呼び出します。

$story = new Story();
$user = new User();
$story->setUser($user);
$em->persist($story);
$em->persist($user);
$em->flush();

または、Storyエンティティのカスケード持続をセットアップします。例えば。注釈マッピングを使用している場合は、次のようにします

/**
 * @ManyToOne(targetEntity="User", inversedBy="stories", cascade={"persist"})
 */
private $author;

8。アソシエーションの操作 の章でこれについて詳しく説明しています。

23
K. Norbert

K.ノーバートの答えはその場に当たりますが、不明確な点があります。少なくともSQLからdoctrineに来た私にとっては不明瞭でした。

doctrineは、どのオブジェクトがすでに永続化されているかを覚えているようです。永続化したいエンティティに関連するnew(まだ永続化されていません)が見つかるたびに、 「関係によって新しいエンティティが見つかりました...」エラー。新しいオブジェクト(1つのエンティティのみ、関連エンティティを永続化せずに)を保存する場合は、関連エンティティが既に永続化されていることを確認するだけで済みます。

$story = new Story();
$entityManager->find('User', $id);
$story->setUser($user);
$em->persist($story);
$em->flush();

トリックを行います。なぜならdoctrineはユーザーがすでに永続化されていることを知っているので、もうそれを行う必要はありません。Doctrineはデータベースからユーザーを取得したので知っています。

5
BartBiczBoży

私はあなたが何を必要としているのか理解するのに苦労しているので、これがあなたの質問に答えるかどうかはわかりません。

Story.user_id idはuser.id(主キー)の外部キーであるため、これを空/ nullにすることはできません。たとえば、phpセッションがある場合、おそらくユーザーID(またはユーザー名)をセッション変数に格納し、ストーリーテーブルに新しいレコードを作成するときに、セッションのユーザーIDを使用してデータを入力します。 story.user_id属性。

それが役に立てば幸い。

0
ophintor

UserUseridではなくstoryを設定する必要があると思いませんか

$user = new User();
$user->setUserId($id);
$story = new Story();
$story->setContent("....");
$story->setUser($user);   //change here
$this->em->persist($story);
$this->em->flush();
0
plain jane

エンティティを添付していただけると助かります。

しかし、私にとっては同様の問題だと思います。 @Idと@ManyToOneを1つのフィールドで一緒に定義することはできません。 @Idとリレーション@ManyToOneには別々のフィールドを使用する必要があります。

新しい(まだ永続化されていない)Userエンティティがある場合、Storyエンティティに対応するフィールドにCascade = {"persist"}またはCascade = {"all"}を持つUserを永続化する必要があります。 Storyエンティティを保存できるのは、Userが既に存在し、Doctrineにアタッチされている場合のみです。

お役に立てば幸いです。

0
Athlan