java - mkyong - Uso simultáneo de datos de Hibernate y Spring jpa?
spring-boot-starter-data-jpa (2)
En lugar de crear una SessionFactory, use EntityManager.unwrap(Session.class)
para obtener una sesión de Hibernate y recuperar la fábrica de sesiones del objeto Session.
También puede usar EntityManagerFactory.unwrap(SessionFactory.class)
para obtener Hibernate SessionFactory directamente.
¿Es posible usar Spring Data JPA (respaldado por Hibernate como proveedor JPA) y usar Hibernate al mismo tiempo?
El problema es que cuando uso JpaTransactionManager, no puedo recuperar la sesión actual con org.hibernate.HibernateException: No Session found for current thread
. Cuando cambio al administrador de HibernateTransaction, los repositorios JPA no pueden confirmar los cambios.
Aquí está la parte de mi contexto Spring (con ese contexto no puedo usar llamadas directas de 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"/>
Ejemplo de repositorio de hibernación:
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();
}
Ejemplo de definición del repositorio de datos de Spring:
public interface BitrateRepository extends PagingAndSortingRepository<Bitrate, Long> { }
Versiones de software:
<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>
Entonces, la pregunta es: ¿es posible usar en la misma transacción (especificada por la anotación @Transactional) repositorios JPA de Spring y llamadas directas de Hibernate y cómo lograr eso?
Necesita una forma única de configuración; ahora está configurando tanto Hibernate como JPA. Debería utilizar JPA para la configuración, de modo que elimine la configuración de hibernación.
Está utilizando Hibernate4 para poder aprovechar el HibernateJpaSessionFactoryBean
de Spring, no tan conocido. Si necesita acceso a SessionFactory
(que supongo que necesita).
Cuando se aplica, a su configuración le gustará algo como esto.
<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>
Yo sugeriría que solo use esto como una solución intermedia mientras está refacturando su aplicación para usar la API simple de JPA. No recomendaría mezclar ambas estrategias.