2009-11-23 21 views
8

JPA + Spring + EJBのToplink実装を使用しています。JPA - persist()を持たない変更を保存

public void updateUser(long userId, String newName){ 
    User u = em.get(User.class, userId); 
    u.setName(newName); 
    // no persist is invoked here 
} 

ので、基本的にこのupdateUser方法が与えられたIDを持つユーザーの名前を更新することになっている:私たちのEJBの一つで、私たちはこのようなものを持っています。 しかし、このメソッドの作成者はem.persist(u)を呼び出すのを忘れていました。

そして、最も奇妙なことは、それがうまく動作することです。どのようにすることができますか?私は がem.persist()またはem.merge()を呼び出さずに100%確実だったので、変更がデータベースに保存されている可能性はありません。彼らは?これが起こる可能性があるシナリオはありますか?

ありがとうございます。

答えて

11

あなたは管理対象エンティティで作業しています。エンティティがエンティティマネージャが閉じられたためにデタッチされない場合、セッションがフラッシュ/クローズされ、トランザクションがコミットされると、エンティティに対して行われたすべての変更がデータベースに反映されます。 Java EE tutorialから

エンティティが 関連するコミットです トランザクションれるとき、永続エンティティの状態がデータベースに を同期しています。

明確さと説明の編集:だからエンティティがそのライフサイクルの間での可能性が3種類のモードがあります。

  • 保存されていない:エンティティがインスタンス化が、persist()していないされていますがまだ呼び出されている。
  • 管理:エンティティはpersist()を使用して永続化されているか、またはデータベースからロードされ、エンティティマネージャセッションに関連付けられています。エンティティへのすべての変更は、エンティティマネージャセッションがフラッシュされたときにデータベースに反映されます。
  • デタッチ:エンティティのエンティティマネージャセッションが閉じられました。エンティティへの変更は自動的にデータベースに反映されませんが、merge()コマンドを使用して明示的にマージできます。
+0

ありがとうございました。これは多くの助けになりました!私は、オブジェクトが現在のEntityManagerに関連付けられていても、em.persist()を呼び出す必要があると常に考えていました。 – anthony

+0

奇妙なこと:私のセットアップでは、管理対象エンティティへの参照があります。次に、このエンティティの状態を変更します。次に、私は 'entityManager.flush()'を呼び出します。これがトランザクション内で実行されている場合、エンティティの変更状態**がデータベースに書き込まれます。これがトランザクションなしで実行されている場合、エンティティの変更状態**はデータベースに書き込まれません**。次のステートメントは本当ですか?:* "objの最新の状態をデータベースに書き込むためには、トランザクションコミットまたは' entityManager.persist(obj) '呼び出しが常に必要です。" * ....私はJPA 2.0をHibernate(4.1.7.Final)で使用しています) – Abdull

+0

@Abdull、はい、JPA仕様では自動コミット動作が定義されていないため、進行中のトランザクションが必要です。 – Henning

関連する問題