2014-02-10 13 views
29

Можно ли использовать Spring Data JPA (поддерживаемый Hibernate как поставщик JPA) и напрямую использовать Hibernate одновременно?Одновременное использование данных Hibernate и Spring jpa?

Проблема в том, что когда я использую JpaTransactionManager, я не могу получить текущий сеанс с org.hibernate.HibernateException: No Session found for current thread. Когда я переключаюсь на HibernateTransaction manager, репозитории JPA не могут фиксировать изменения.

Вот часть моего Спринг контекста (с этим контекстом я не в состоянии использовать прямые вызовы 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(); 
} 

Пример весна определение хранилища данных:

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 вызовов и как достичь этого?

ответ

18

Вместо создания SessionFactory используйте EntityManager.unwrap(Session.class) для получения сеанса Hibernate и получения фабрики сеансов из объекта Session.

Вы также можете использовать EntityManagerFactory.unwrap(SessionFactory.class), чтобы получить Hibernate SessionFactory напрямую.

+2

Было бы немного более полезно, если бы вы включили пакет. В Spring есть миллиарды пакетов, и Eclipse не находит EntityManager сам по себе ... – user1944491

+0

Для этого вам нужна JPA javax.persistence.EntityManager –

22

Вам нужен один способ конфигурации, который вы теперь настраиваете как Hibernate, так и JPA. Вы должны использовать JPA для настройки, чтобы удалить настройку спящего режима.

Вы используете Hibernate4, чтобы использовать преимущества, которые не так хорошо известны, HibernateJpaSessionFactoryBean of Spring. Если вам нужен доступ к SessionFactory (который, как я полагаю, вам нужен).

При использовании вашей конфигурации вам понравится что-то подобное.

<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> 

Я хотел бы предложить только использовать это в качестве промежуточного решения, когда вы рефакторинга ваш applicaiton использовать простой JPA API. Я бы не предложил смешивать обе стратегии.

+2

Это лучше, чем мы рекомендуем в наших [справочных документах] (http: // docs.spring.io/spring-data/jpa/docs/current/reference/html/faq.html#d0e2924). Не могли бы вы создать билет, чтобы улучшить документы? Не возражаю против запроса на тягу :). –

+4

@OliverGierke [Готово] (https://jira.springsource.org/browse/DATAJPA-462) & [Done] (https://github.com/spring-projects/spring-data-jpa/pull/57) , –

+0

@ M.Deinum Я подтвердил, что он не очень хорошо известен, но очень изящный! один вопрос (любопытство): почему бы вам не смешать обе стратегии? –

Смежные вопросы