Hibernate5 SessionImpl无法识别JpaTransactionManager启动的事务
我最近将旧版Java Web应用程序迁移到了Spring-boot Hibernate。球衣已在旧版应用中使用,因此继续使用spring-boot-starter-jersey。所以堆栈是:
RestfulService(Jersey)-> Spring Service-> Hibernate DAO(旧版代码)。
Spring服务和Hibernate DAO都通过各自的公共接口使用,并且在实现类的公共方法上具有@Transactional。
休眠DAO看起来像:
@存储库 公共类UserDaoImpl实现UserDao {
@Autowired
@Qualifier("entityManagerFactory")
EntityManagerFactory entityManagerFactory;
public SessionFactory getSessionFactory() {
return entityManagerFactory.unwrap(SessionFactory.class);
}
@Override
public User getUserByUserName(String userName) throws Exception {
User user = null;
Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(User.class);
criteria.add(Restrictions.eq("userName", userName));
user = (User) criteria.uniqueResult();
return user;
}
}
使用 JpaTransactionManager 时出现异常:
javax.persistence.TransactionRequiredException: no transaction is in progress.
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3505)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1427)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1423)
at org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:147)
at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:96)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:922)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:730)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:532)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:304)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.iotu.serviceImpl.UserServiceImpl$$EnhancerBySpringCGLIB$$d0c10f8c.checkLoginDetails(<generated>)
at com.iotu.webservices.UserWS.userAuthentication(UserWS.java:1467)
at com.iotu.webservices.UserWS$$FastClassBySpringCGLIB$$66e6577d.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)
at com.iotu.webservices.UserWS$$EnhancerBySpringCGLIB$$99ca5efe.userAuthentication(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:76)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:148)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:191)
切换到 HibernateTransactionManager ,Hibernate能够识别正在进行的事务。没有异常。
@Configuration
@EnableJpaRepositories("com.app.repository")
public class AppConfiguration {
@Bean
public HibernateTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
SessionFactory sf = entityManagerFactory.unwrap(SessionFactory.class);
return new HibernateTransactionManager(sf);
}
但是它有缺点。对于较新的功能,我正在使用spring数据存储库。使用HibernateTransactionManager,JpaRepository的save方法不适用于实体。它不会触发更新sql(控制台上没有错误)。 findXX方法工作正常。
@Repository
public interface LessonCategoryRepository extends JpaRepository<LessonCategory, Long> {
public List<LessonCategory> findByCategoryAndLanguage(@Param("category") String category, @Param("language") String language);
}
当我切换到JpaTransactionManager时,通过JpaRepository进行的更新工作正常,但开始获取javax.persistence.TransactionRequiredException:使用遗留DAO类的服务调用未进行任何事务。
总结:
我可以使JpaTransactionManager与现有的休眠DAO类一起使用吗?要么 我可以使HibernateTransactionManager与JpaRepository一起使用吗? ..这样我就可以按原样使用旧版DAO类,但可以继续使用JpaRepositories。