私は、Hibernate セッションを理解できないもう 1 人の初心者だと思います。Spring の TransactionTemplate かもしれません。これが私の話です。
私はHibernate 3.5.5-Final、Spring 3.0.4.RELEASEを使用しており、注釈のみで生きようとしています(HibernateとSpring MVCの場合)。
私の最初の試みは、適切に設定されたトランザクション マネージャーと組み合わせて @Transactional アノテーションを使用することでした。最初はうまくいったように見えましたが、長い目で見ると (約 36 時間)、何度も "LazyInitializationExceptions" を受け取るようになりました (前の時間には問題なく実行されていた場所から!)。
そのため、Spring TransactionTemplate を使用して手動トランザクションに切り替えました。
基本的に、私は BaseService にこの保護されたもののようなものを持っています
@Autowired
protected HibernateTransactionManager transactionManager;
protected void inTransaction(final Runnable runnable) {
TransactionTemplate transaction = new TransactionTemplate(transactionManager);
transaction.execute(new TransactionCallback<Boolean>() {
@Override
public Boolean doInTransaction(TransactionStatus status) {
try {
runnable.run();
return true;
} catch (Exception e) {
status.setRollbackOnly();
log.error("Exception in transaction.", e));
throw new RuntimeException("Exception in transaction.", e);
}
}
});
}
そして、サービスの実装からこのメソッドを使用しても問題なく動作し、LazyInitializationException は 10 日間表示されませんでした (Tomcat をこの単一のアプリで 24*7 で 10 日間実行し、再起動しませんでした) ... しかし、フープよりも! それは再びポップしました:-/
LazyInitializationException は「inTransaction」メソッドの下の場所から発生し、「inTransaction 再帰」は含まれていないため、同じ Hibernate セッションで悲しいことに同じトランザクションにいる必要があると確信しています。関連する「前のセッションからのデータ」はありません(私のコードが行く限り、サービスレイヤーはトランザクションを開き、必要なHibernateからすべてのデータを収集し、それを処理して結果を返します==サービスは他のトップサービスをリコールしません)
私は自分のアプリをプロファイリングしていません (10 日間などの長期実行でそれを適切に行う方法さえ知りません) が、私の唯一の推測は、どこかでメモリ リークが発生しており、JVM がヒープ制限に達していることです... ありますか? SpringまたはHibernat内に含まれるいくつかの「SoftReferences」? 知らない...
もう 1 つの面白い点は、Google GSON シリアライザーを使用して結果を JSON にシリアライズしようとすると、常に例外が発生することです。私はゲッターを使用していないことを知っています...実際のフィールドの代わりにゲッターを使用している独自のパッチを適用したバージョンがあります (そのため、Hibernate プロキシメカニズムをバイパスしないようにしています)。ここで何らかの役割を果たすと思いますか?
最後の面白い点は、例外が常に単一のサービスメソッドで発生していることです (他の場所ではありません)。レイジーフェッチを使用して JSON に)、ハァッ???
何を試すべきか提案はありますか?似たような経験はありませんか?
ありがとう、ヤクブ