0

トランザクション サービス メソッド内で、データベースへのクエリをループして、エンティティ A の最初の 10 個を条件付きで取得します。

リストから各 A エンティティを更新して、基準に一致しないようにし、flush() を呼び出して変更が行われたことを確認します。

ループ内のクエリへの 2 回目の呼び出しは、まったく同じ A エンティティのセットを返します。

エンティティのフラッシュされた変更が考慮されないのはなぜですか?

Hibernate 4.1.7 で JPA 2.0 を使用しています。Hibernate のみで同じプロセスが機能しているようです。セカンド レベル キャッシュとクエリ キャッシュをオフにしましたが、役に立ちませんでした。

私はかなり単純な構成、JpaTransactionManager、Spring over JPA over Hibernate を使用しています。@Transactional アノテーションが付けられたメイン メソッド。

コードは次のようになります。

do {
    modelList = exportContributionDao.getContributionListToExport(10);
    for (M m : modelList) {
        //export m to a file
    m. (false);
    super.flush();
    }
} while (modelList.size() == 10);

ループの反復ごとに、Dao メソッドは常に同じ 10 個の結果を返します。JPA は、更新された「isToBeExported」属性を考慮しません。

問題を解決しようとしているのではなく、ここで JPA が期待どおりに動作しない理由を理解したいのです。これは「古典的な」問題だと思います。反復ごとにトランザクションがコミットされれば、問題は解決することは間違いありません。

ASAIK、キャッシュ L1、つまり基礎となる JPA プロバイダーとして Hibernate を使用するセッションは最新である必要があり、変更がまだ永続化されていなくても、2 番目の反復クエリは更新されたエンティティを考慮する必要があります。だから私の質問は:なぜそうではないのですか?設定ミスか既知の動作か?

4

2 に答える 2

1

フラッシュは、必ずしもデータベースの変更をコミットするわけではありません。何を達成したいですか?私が理解していることから、あなたはs.thをします。お気に入り:

  1. エンティティについてループする
  2. ループ内で、エンティティを変更します
  3. エンティティで「フラッシュ」を呼び出します
  4. エンティティをもう一度読み直してください
  5. なぜデータベースのデータが変更されなかったのか疑問に思いますか?

これが正しければ、なぜ変更を読み直して、要素を操作しないのですか?トランザクションを終了すると、変更は自動的に永続化されます。

于 2012-12-10T12:36:35.157 に答える
0

これは間違いなく機能するはずです。

これは、当社側の構成上の問題です。

質問についてお詫び申し上げます。私たちの側で理由を見つけるのはかなり困難でしたが、答えが少なくとも一部の人にとって役立つことを願っています:

JPA は、単一のトランザクション内でエンティティに加えられた変更を確実に考慮します。

于 2012-12-11T11:03:34.237 に答える