0

次のようにマップされItemListた一連のクラスを含むクラスがあります。Items

<class name="ItemList">
   <id name="PID" column="PID">
      <generator class="uuid" />
   </id>
   <version name="Version" />
   <set cascaed="save-update" name="Items">
      <key column="itemlist_id" />
      <one-to-many class="Item" />
   </set>
</class>

<class name="Item">
   <id name="PID" column="PID">
      <generator class="uuid" />
   </id>
   ...
</class>

これは一方向の関連付けです。に数千をバッチ挿入する必要がありItemsますItemList。バッチ挿入で休止状態のドキュメントを使用すると、次のようなものがあります。

ItemList itemList = ...

int i = 0;
for (Item item : someItems) {
    // .. some processing..

    itemList.getItems().add(item);

    if (++i % 30 == 0) {
       session.update(itemList);
       session.flush();
       session.clear();
    }
}

明らかにいくつかの問題があります。フラッシュごとに 30 個のアイテムが挿入されます。その後、ItemList のバージョンが更新されます。次に、ItemList の PID で 30 個のアイテムすべてが更新されます。

  1. 各バッチの後で ItemList のバージョンをインクリメントしないようにするにはどうすればよいですか?
  2. 30 回の更新を回避するにはどうすればよいですか?
4

1 に答える 1

0
  1. 申し訳ありませんが、それについてはお手伝いできません (しかし、なぜ気にするのですか?)。

  2. 30アイテムごとに更新ということですか?Item何千ものすべてがセッションレベルのキャッシュに保存されるため、メモリ不足のリスクを冒すつもりがない限り、あなたも望んでいません。

  3. 状態のドキュメントとして、次の理由で機能します。Session.flush()

フラッシュは、基になる永続ストアを、メモリに保持されている永続状態と同期させるプロセスです。

したがって、フラッシュが完了し、最後の 30 項目が適切に処理された後、それらは DB 側にあります。ただし、コミットしているわけではありません。DB は、まだコミットされていないトランザクションの最中であることを認識しています。

編集

バージョンが各flush. 私はここで推測しています。Hibernate はこのversion列を使用して、トランザクションが開始されてから、現在のトランザクションによって変更されたエンティティが他のトランザクションによって変更されていないことを確認します。ただし、この検証は Hibernate に代わってのみ行われ、DB 固有の機能は使用されません。versionバージョン テーブルの DDL が列がプレーンであることを示しているため、これは正しいと思います。int(Hibernate はクロス DB ベンダー API ですが、OTOH は各ベンダーに固有のツールを使用できるため、これも理にかなっています)。そのため、フラッシュの直前に、Hibernate には、フラッシュされたエンティティが古いデータではないことを確認する最後のチャンスがあります。フラッシュ後、これらの更新されたエンティティは更新用にマークされないため、将来のフラッシュは、同じトランザクションであっても、バージョン検証イベントを発生させません。

于 2012-06-26T00:52:49.670 に答える