2016-08-09 7 views
3

Я пытался оборачивать голову вокруг этой проблемы весь день.Hibernate Envers не находит транзакции JPA:

В настоящее время в нашем проекте установлена ​​программа JPATransactionManager через контекст Spring Application Context, чтобы позаботиться о наших различных сеансовых транзакциях с использованием @Transactional для всех служб, которые заботятся о сохранении и удалении (использование DAO).

Изменение с Hibernate с 3 по 5, мы хотели удалить наше использование настраиваемого контрольного перехватчика и перейти на использование Hibernate Envers. Я аннотированный все мои классы правильно и таблицы создаются, но как только он на самом деле попадает в точку вставки, слушатель выдает ошибку, в которой он не может найти текущую транзакцию, данное JPA:

 
org.hibernate.envers.exception.AuditException: Unable to create revision because of non-active transaction 
    at org.hibernate.envers.event.spi.BaseEnversEventListener.checkIfTransactionInProgress(BaseEnversEventListener.java:132) 
    at org.hibernate.envers.event.spi.EnversPostInsertEventListenerImpl.onPostInsert(EnversPostInsertEventListenerImpl.java:34) 
    at org.hibernate.action.internal.EntityIdentityInsertAction.postInsert(EntityIdentityInsertAction.java:156) 
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:102) 
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:597) 
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:232) 
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:213) 
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:256) 
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182) 
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113) 
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192) 
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177) 
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:97) 
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73) 
    at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:651) 
    at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:643) 
    at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:638) 

Внутри кода кажется, что он основывает статус транзакции на значение по умолчанию для НЕАКТИВНОГО значения, означающее, что он не подключается к транзакции должным образом. Я знаю, что Hibernate Envers также автоматически подталкивает слушателей в спящий режим с помощью последних версий, поэтому я не знаю, может ли это быть источником проблемы.

Я знаю, что он был документирован для работы с HibernateTransactionManager, но мы хотим отказаться от использования этого в пользу подключения наших транзакций и сеансов исключительно с помощью Spring, что упростит работу, поэтому также может потребоваться найти альтернативу Envers. Есть ли у кого-нибудь советы или решения этой проблемы? Или также ударить по этой проблеме?

applicationContext.xml

<tx:annotation-driven transaction-manager="transactionManager" /> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="dataSource" ref=“dataSource" /> 
</bean> 

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
    <property name="driverClassName" value="net.sourceforge.jtds.jdbcx.JtdsDataSource" /> 
    <property name="url" value="jdbc:jtds:sqlserver://.." /> 
    <property name="username" value=“..." /> 
    <property name="password" value=“..." /> 
</bean> 

<bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> 
    <property name="location"> 
     <value>classpath:hibernate.properties</value> 
    </property> 
</bean> 

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> 
    <property name="configLocation"> 
     <value>classpath:hibernate.cfg.xml</value> 
    </property> 
    <property name="hibernateProperties"> 
     <ref bean="hibernateProperties" /> 
    </property> 
</bean> 

<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
    <property name="transactionManager"> 
     <ref bean="transactionManager" /> 
    </property> 
    <property name="transactionAttributes"> 
     <props> 
      <prop key="find*">PROPAGATION_SUPPORTS,readOnly 
      </prop> 
      <prop key="load*">PROPAGATION_SUPPORTS,readOnly 
      </prop> 
      <prop key="make*">PROPAGATION_REQUIRED</prop> 
      <prop key="add*">PROPAGATION_REQUIRED</prop> 
      <prop key="refresh">PROPAGATION_SUPPORTS</prop> 
      <prop key="delete*">PROPAGATION_REQUIRED</prop> 
      <prop key="*">PROPAGATION_SUPPORTS,readOnly 
      </prop> 
     </props> 
    </property> 
</bean> 

<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy"> 
    <property name="transactionManager" ref="transactionManager" /> 
</bean> 

hibernate.properties

#hibernate.hbm2ddl.auto=update 
hibernate.show_sql=true 

hibernate.connection.datasource=java\:comp/env/datasource 
#hibernate.connection.provider_class=org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl 
hibernate.connection.provider_class=org.hibernate.connection.DatasourceConnectionProvider 

hibernate.cache.use_second_level_cache=true 
hibernate.cache.use_query_cache=true 
#hibernate.generate_statistics=true 
hibernate.cache.use_structured_entries=true 
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider 
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory 
hibernate.id.new_generator_mappings=false 

hibernate.dialect=org.hibernate.dialect.SQLServer2008Dialect 

hibernate.listeners.envers.autoRegister=false 
org.hibernate.envers.track_entities_changed_in_revision=false 
org.hibernate.envers.audit_table_prefix=AUD_ 
org.hibernate.envers.audit_table_suffix= 

Мои объекты DAO подключены с помощью txProxyTemplate как так

<bean id="objectDAO" parent="txProxyTemplate"> 
    <property name="target"> 
     <bean 
      class="path.to.objectDAOImpl"> 
      <property name="sessionFactory"> 
       <ref local="sessionFactory" /> 
      </property> 
     </bean> 
    </property> 
</bean> 

Все мои ы ervices, которые используют различные DAO, просто подключаются с помощью аннотации @Transactional, где мы хотим иметь транзакции. Я смог проследить, что мои транзакции преуспевают в завершении и откате, когда возникают ошибки. Когда я добавлю переменные в микс, аудит не сможет найти транзакцию для присоединения. Должно быть, что-то мне не хватает, но я не уверен, что это такое.

+0

Можете ли вы обновить сообщение своим конфигурацией пружины для EntityManagerFactoryBean, TransactionManager и т. Д.? У меня нет таких проблем с Envers в полностью настроенной пружинной среде. – Naros

+0

Просто расширил пример моей текущей конфигурацией. Извините за поздний ответ! –

ответ

0

Я не считаю, что вам нужно определить bean txProxyTemplate или SpringTransactionPolicy из моего опыта. С тех пор эта функциональность была заменена тегами <tx:/> и использованием аннотации @Transactional.

Вам просто нужно убедиться, что JpaTransactionManager был создан и ассоциирован как transactionManager, связанный с тегом <tx:annotation-driven/>.