hibernate 4 spring 4: отложенная загрузка - не удалось получить сеанс с синхронизацией транзакций для текущего потока
Я добавил аспект аспект ленивой загрузки для сеанса инициализации. После перехода на Spring 4, Hibernate 4, Java 8 получил исключение:
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
Конфигурация Hibernate:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="reattachSessionAspect" class="prj.ReattachSessionAspect" factory-method="aspectOf"/>
<bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
// model packages
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.internal.NoCachingRegionFactory</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.connection.autocommit">true</prop>
<prop key="hibernate.connection.release_mode">after_statement</prop>
<prop key="hibernate.connection.pool_size">0</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
Класс Aspect (исключение вызвано sessionFactory.getCurrentSession()):
@Aspect
public class Aspect {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
private static ThreadLocal<Boolean> LOCK = new ThreadLocal<Boolean>();
@Around("reattachSession()")
public Object reattachSession(ProceedingJoinPoint pjp) throws Throwable {
Object obj = pjp.proceed();
if (obj instanceof AbstractPersistentCollection) {
AbstractPersistentCollection ps = (AbstractPersistentCollection) obj;
Field field = getClass(ps.getClass()).getDeclaredField("session");
field.setAccessible(true);
SessionImpl o = (SessionImpl)field.get(ps);
if (!ps.wasInitialized() && (o == null || o.isClosed()) && (LOCK.get()==null || !LOCK.get())) {
LOCK.set(true);
Transaction t = null;
try {
Session session = sessionFactory.getCurrentSession();
t = session.beginTransaction();
session.update(pjp.getTarget());
Hibernate.initialize(ps);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if (t != null && t.isActive()) {
t.rollback();
}
throw new RuntimeException(e);
} finally {
LOCK.set(false);
}
}
}
return obj;
}
private Class getClass(Class clazz) {
if(clazz.equals(AbstractPersistentCollection.class)){
return clazz;
} else {
return getClass(clazz.getSuperclass());
}
}
@Pointcut("execution(@prj.AddSession * *(..))")
public void reattachSession(){
}
}
Метод, вызывающий исключение при вызове:
@Lazy
@Transactional(propagation = Propagation.REQUIRED)
public List<Detail> getDetails() {
return details;
}
В сервисных слоях сессия налаживается И до миграции все работало. Перед миграцией у меня был current_session_context_class=thread.
Может кто-нибудь посоветовать мне, что я делаю не так?