15

JPA + Spring + EJB の Toplink 実装を使用しています。EJB の 1 つには、次のようなものがあります。

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

したがって、基本的にこのupdateUser()メソッドは、指定された .xml でユーザーの名前を更新することになっていますuserId。しかし、このメソッドの作成者は を呼び出すのを忘れていましたem.persist(u)

そして最も奇妙なことは、それがうまく機能することです。どうしてですか?em.persist()呼び出さないem.merge()と、変更がデータベースに保存される可能性がないことを100%確信していました。彼らはできますか?これが発生するシナリオはありますか?

4

1 に答える 1

16

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

Java EE チュートリアルから:

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

明確さと説明のために編集してください:したがって、エンティティがそのライフサイクル中に存在する可能性がある3つの異なるモードがあります。

  • Unsaved : エンティティはインスタンス化されていますが、persist()まだ呼び出されていません。
  • Managed : エンティティは を使用して永続化されているpersist()か、データベースからロードされており、エンティティ マネージャ セッションに関連付けられています。エンティティ マネージャ セッションがフラッシュされると、エンティティに対するすべての変更がデータベースに反映されます。
  • Detached : エンティティのエンティティ マネージャ セッションが閉じられました。エンティティへの変更はデータベースに自動的に反映されませんが、merge()コマンドを使用して明示的にマージできます。
于 2009-11-23T18:44:11.837 に答える