1

次のコードは、「em.refresh(p)」を呼び出すときに例外をスローします。

1: EntityManager em = emf.createEntityManager();
2: em.getTransaction().begin();
3:
4: Product p = new Product("J&D", 35.0,"Whisky");
5: em.persist(p);
6:
7: em.refresh(p);
8: em.getTransaction().commit();
9: em.close();

コードをデバッグすると、6 行目で Hibernate がレコードを DB に書き込んでいないことがわかります。

7 行目で、次の例外が発生します: Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.HibernateException: this instance does not still exist as a row in the database

6 行目で Hibernate に強制的にレコードを DB にフラッシュさせると、INSERT が実行され、エラーは発生しません。select を実行するか、単にフラッシュを強制することでこれを行うことができます (すべての結果を伴います)。

6 : em.createQuery("select p from Product p").getResultList();
6 : em.flush();

私の質問:メソッド「リフレッシュ」は、前に配置されたselectまたはflushステートメントのように、HibernateにレコードをDBに強制的に書き込まないようにする必要がありますか? (これはバグでしょうか?)。

ご回答ありがとうございます。

ピエール

4

1 に答える 1

5

メソッド「リフレッシュ」は、前に配置されたときに select または flush ステートメントが行うように、Hibernate にレコードを DB に書き込むように強制しないでください。(これはバグでしょうか?)。

いいえ、現在のトランザクションで行われたフラッシュされていない変更を元に戻すことrefreshが全体のポイントでrefreshあるため、変更をフラッシュしないでください。これは、仕様よりも JPA wiki ブックで説明されている可能性があります。

この EntityManager#refresh(Object) 操作は、データベースからオブジェクトの状態を更新するために使用されます。これにより、現在のトランザクションで行われたフラッシュされていない変更がオブジェクトに戻され、その状態がデータベースで現在定義されている状態に更新されます。が発生した場合は、flushフラッシュされたものに更新されます。Refresh はマネージド オブジェクトで呼び出す必要があるため、非マネージド インスタンスがある場合は、最初findにアクティブなオブジェクトが必要になる場合があります。EntityManager

したがって、コードを機能させたい場合はflush、実際に実行する必要があります。persist

refreshそうは言っても、(変更をフラッシュしたと仮定して)直後に aを実行する意味がわかりませんpersist。ここで更新するものは何もありません。単純化した例かもしれませんが。

参考文献

  • JPA 2.0 仕様
    • 3.2.5 エンティティ インスタンスの更新
  • JPAウィキブック
于 2010-10-23T14:17:00.567 に答える