この質問の根本は、同期の失敗の原因は何でしょうか。これは単に「何かがうまくいかなかった」という意味の一般的なメッセージですか、それともセッション自体に実際に何か問題がありますか? 同様のタイトルのスレッドがいくつかありますが、hibernateがセッションの同期に失敗する理由に実際に対処しているものはないようです。これは、人々が無視するエラーメッセージの一部にすぎません。
私の特定のケース/詳細(上記の質問に実際に接していますが):
データのインポート中(20〜120分)、大量の処理を行っています。ドメインオブジェクトのセット全体が構築され、整合性が検証されるまで、永続性は開始されません。この間、私は約200,000のドメインオブジェクトを構築します。プロセスの最後に、それらすべてをループしてデータベースに保存し、(パフォーマンス上の理由から)50または100オブジェクトごとにセッションをフラッシュ/クリアします。永続化が開始されると、ドメインオブジェクトは変更されません。
これはすべて、単一のサービス呼び出し、単一のトランザクション内で発生します。また、これをテストシステムで再現することはできません。これは、本番環境でのみ発生しています。
私はdomainObj.save()
ではなくを使用しsession.saveOrUpdate(domainObj)
ています。手動でセッションに触れるのは、一連の更新後にセッションをフラッシュ/クリーニングする場合のみです。
def session = sessionFactory.currentSession
session.flush()
session.clear()
これは、例外がスローされる場所です。
同期に失敗したメッセージの直後は次のとおりです(おそらく結果ですが、原因に関連している可能性があります)。
Could not execute JDBC batch update; SQL [insert into domainB(field1, field2, etc) values (?, ?, ?)];
nested exception is org.hibernate.exception.ConstrainViolationException: Could not execute JDBC batch update
このConstrainViolation(はい、「constraint」ではなく「constrain」)はデータエラーのように見えますが、データセットは機能しており、インポートファイルまたはコードを変更せずにこのエラーをスローし始めました。他のシステムでも動作し続けるので、比較的ある程度データエラーを排除しました。
オブジェクトの関係の性質上、同じオブジェクトが複数回保存されていることはほぼ間違いありません。これはパフォーマンスを改善するためのもう1つの場所ですが、オブジェクトを保存したらIDを割り当て、再保存してもエラーが発生しないため、関係はないと思います。
私はこの時点でとりとめのない話と憶測に陥っています。誰かに私の問題を解決してほしくないのですが、誰かがセッションの同期について明確に何かを知っていて、「重複データを挿入していないことを確認しましたか? 「」私はできる限り確信しているからです(保存するドメインオブジェクトを検索するためのキーとして制約された一意のフィールドを使用してHashmap.keySet()を繰り返します)。