是否可以使用Spring Data JPA(由Hibernate作为JPA提供者支持)并同时直接使用Hibernate?
问题是,当我使用JpaTransactionManager时,无法使用检索当前会话org.hibernate.HibernateException: No Session found for current thread。当我切换到HibernateTransaction Manager时,JPA存储库无法提交更改。
org.hibernate.HibernateException: No Session found for current thread
这是我的Spring上下文的一部分(在该上下文中,我无法使用直接的Hibernate调用):
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/IPGCONF"/> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" p:dataSource-ref="dataSource"> <property name="configLocation" value="classpath:hibernate.cfg.xml"/> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="entityManagerFactory"/> <property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <jpa:repositories base-package="com.satgate"/>
hibernate存储库示例:
public Collection<Layer> listCurrent(Carrier carrier) { Criteria query = sessionFactory.getCurrentSession() .createCriteria(Layer.class) .add(Restrictions.eq("carrier", carrier)); query.createCriteria("bitrate") .addOrder(Order.desc("bitrate")) .add(Restrictions.eq("symbolrate", carrier.getSymbolrate())); return query.list(); }
Spring数据存储库定义示例:
public interface BitrateRepository extends PagingAndSortingRepository<Bitrate, Long> { }
软件版本:
<org.springframework.version>4.0.0.RELEASE</org.springframework.version> <org.springframework.data.version>1.4.3.RELEASE</org.springframework.data.version> <hibernate.version>4.3.0.Final</hibernate.version>
因此,问题是-Spring JPA存储库和直接的Hibernate调用是否可以在同一事务中使用(由@Transactional注释指定),如何实现?
与其创建SessionFactory,不如使用EntityManager.unwrap(Session.class)Hibernate Session并从Session对象检索会话工厂。
EntityManager.unwrap(Session.class)
您也可以使用EntityManagerFactory.unwrap(SessionFactory.class)直接获取Hibernate SessionFactory。
EntityManagerFactory.unwrap(SessionFactory.class)