1

現在データベースにあるエンティティと保存されたばかりのオブジェクトを必要とするメソッド (compareEntities ) を実行したいと思います。emがEntityManagerである私のDAOでこのようなもの:

public void save(MyObj myObj) {
    MyObj previous = null;
    MyObj current = null;
    Integer id = myObj.getId();     
    if (id == null) {
        // new
        current = em.persist(myObj);
    } else {
        previous = em.find(MyObj.class, id);
        // update
        current = em.merge(myObj);
    }
    compareEntities (previous, current);
}

問題は、保存されるエンティティがデータベースから取得され、それにいくつかの変更を加えたときに、データベースからデータを取得しようとすると (find メソッドを使用して)、変更されたデータを取得することです。エンティティが永続コンテキストで見つかったためです。同じトランザクション内のエンティティに変更を加えずに、データベースにあるデータを取得する方法はありますか?

ありがとう。

4

1 に答える 1

1

現在アタッチされている同じエンティティの変更されたインスタンスを持つ永続コンテキストを使用して、変更されていないエンティティを見つける信頼できる方法はありません。永続化プロバイダーが変更をデータベースにフラッシュした可能性があります。その場合、変更されたSELECTオブジェクトが後続のに表示されます。これは、トランザクション内で現在のものであるためです。永続化プロバイダーがまだ変更をフラッシュしていない場合でも、仕様では、同じキーの呼び出しから同じインスタンスを返す必要があります。「変更されていない」オブジェクトを返すことは許可されていません。find

新しいトランザクションからデータを取得するには、別の接続を使用する必要があります。その方法は、プログラミング モデルによって異なります。EJB3 のようなコンテナー管理のトランザクションを使用する JTA プログラミング モデルでは、@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)アノテーション付きのビジネス メソッドを使用します。プレーンな JPA では、新しい EntityManager とfindオブジェクトを ID で取得します。

監査ログ システムを実装しようとしていると思われます。その場合は、Hibernate Envers、PostgreSQL audit trigger example、または標準の JPA エンティティ リスナーを参照してください。これらはすべて、このタスクを達成するためのより優れた方法を提供します。解決しようとしている根本的な問題、この質問の「方法」の「理由」を説明してみてください。

于 2012-10-17T05:32:55.133 に答える