Hibernate Session
はスレッドセーフではないため、現在のスレッドの現在のセッションを取得する方法が必要です。そのような戦略はCurrentSessionContext
と呼ばれます。
現在のセッションでは、我々は、この呼び出しによって取得したセッションです:
sessionFactory.getCurrentSession()
Hibernateは様々な現在のセッションの戦略を使用して設定することができます。 @UnitOfWork
は、この戦略使用しています。私たちはSession
はスレッドセーフではない知っているように、だから
ManagedSessionContext.bind(session)
の明示的な呼び出しによってコンテキストにセッションを置くために、あなたがしなければならない。この戦略の
hibernate.current_session_context_class = managed
をお別のスレッドのために新しいセッションを作成し、そのセッションをManagedSessionContext
に入れるべきです。その後、@UnitOfWork
のエンドポイントメソッドと同じ方法でDAOを呼び出すことができます。 guava
から
public final class HibernateSessionUtils {
private HibernateSessionUtils() {
}
public static void request(SessionFactory factory, Runnable request) {
request(factory,() -> {
request.run();
return null;
});
}
public static <T> T request(SessionFactory factory, Supplier<T> request) {
Transaction txn = null;
Session session = factory.openSession();
try {
ManagedSessionContext.bind(session);
txn = session.beginTransaction();
T result = request.get();
commit(txn);
return result;
} catch (Throwable th) {
rollback(txn);
throw Throwables.propagate(th);
} finally {
session.close();
ManagedSessionContext.unbind(factory);
}
}
private static void rollback(Transaction txn) {
if (txn != null && txn.isActive()) {
txn.rollback();
}
}
private static void commit(Transaction txn) {
if (txn != null && txn.isActive()) {
txn.commit();
}
}
}
Throwables
:
はあなたが別のスレッドのセッションを作成するには、このユーティリティクラスを使用することができます
ManagedSessionContext.unbind(factory)
でそれを閉じる前に、セッションをアンバインドする必要があります覚えておいてください。
それはあなたがあなたがGuice
を使用して、どこでも工場を注入することができるセッション
sessionFactory.getCurrentSession()
を得ることができますdao.getCampaigns()
方法では、このよう
List<Campaign> getCampaigns(SessionFactory factory, CampaignDao dao) {
return HibernateSessionUtils.request(
factory,
dao::getCampaigns
);
}
で使用することができます。
その他のオプションはUnitOfWorkAwareProxyFactory
です。