同时使用Hibernate和Spring data jpa?

2022-09-01 08:50:47

是否可以使用Spring Data JPA(由Hibernate作为JPA提供者支持)并同时直接使用Hibernate?

问题是,当我使用JpaTransactionManager时,我无法检索当前会话。当我切换到HibernateTransaction管理器时,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"/>

休眠存储库示例:

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>

所以,问题是 - 是否可以在同一事务(由@Transactional注释指定)同时使用Spring JPA存储库和直接Hibernate调用,以及如何实现这一点?


答案 1

您需要一种单一的配置方式,您现在正在同时配置Hibernate和JPA。您应该使用 JPA 进行配置,因此请删除休眠设置。

您正在使用Hibernate4,因此您可以利用Spring的不太知名的功能。如果您需要访问(我假设您需要)。HibernateJpaSessionFactoryBeanSessionFactory

应用后,您的配置将像这样。

<bean id="sessionFactory" class="org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</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>

我建议在重构应用程序以使用普通 JPA api 时仅将其用作中间解决方案。我不建议混合这两种策略。


答案 2

不要创建会话网站,而是使用 来获取休眠会话并从 Session 对象中检索会话工厂。EntityManager.unwrap(Session.class)

您也可以使用直接获取Hibernate SessionFactory。EntityManagerFactory.unwrap(SessionFactory.class)


推荐