19

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

ユーザーがストーリーテーブルに保存されている多くのストーリーを持つことができるという関係を設定しました。両方のテーブルのエンティティを作成しました。

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

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

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

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

Storyエンティティに ManyToOne 関係を設定します。

/**
 * @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();
4

5 に答える 5

30

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

$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. 関連付けの操作では、これについて詳しく説明しています。

于 2013-03-24T00:34:32.097 に答える
6

K. Norbert の回答は的を射ていますが、不明な点があります。少なくとも、SQL から教義を学ぶようになった私にはわかりませんでした。

問題は、ドクトリンは、どのオブジェクトがすでに永続化されているかを覚えているようです。永続化したいエンティティに関連する新しい(まだ永続化されていない) オブジェクトが見つかると、「関係を通じて新しいエンティティが見つかりました ...」というエラーが表示されます。新しいオブジェクト (関連するエンティティを永続化せずに 1 つのエンティティのみ) を保存する場合は、関連するエンティティが既に永続化されていることを確認する必要があります。そう:

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

トリックを行います。doctrine は、ユーザーが既に永続化されていることを認識しており、もうそれを行う必要がないためです。データベースからユーザーを取得したため、Doctrine は認識しています。

于 2015-03-07T06:56:53.667 に答える
1

forUserではなく設定する必要があると思いますかUseridstory

$user = new User();
$user->setUserId($id);
$story = new Story();
$story->setContent("....");
$story->setUser($user);   //change here
$this->em->persist($story);
$this->em->flush();
于 2013-10-16T09:54:20.217 に答える
0

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

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

それが役に立てば幸い。

于 2013-03-23T12:09:22.727 に答える
0

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

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

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

それが役立つことを願っています。

于 2013-03-23T17:43:38.950 に答える