Подтвердить что ты не робот

Одновременное использование данных Hibernate и Spring jpa?

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

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

Вот часть моего контекста 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 и как это сделать?

4b9b3361

Ответ 1

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

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

Ответ 2

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

Вы используете Hibernate4, чтобы вы могли использовать не очень хорошо известный HibernateJpaSessionFactoryBean из 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>

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