JPA2.0 / Hibernate - hibernate的EmptyInterceptor的事务问题

时间:2014-03-20 15:06:41

标签: hibernate jpa-2.0 interceptor

我在Hibernate的应用程序中使用JPA2.0。出于审计日志记录的目的,我使用的是Hibernate的' org.hibernate.EmptyInterceptor '。我的配置如下所示:

<bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        p:persistenceUnitName="EvolutionPU"
        p:persistenceXmlLocation="classpath*:persistence.xml"
        p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter">
        <property name="loadTimeWeaver">
            <bean
                class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
        <property name="jpaProperties">
            <props>
                  <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
                  <prop key="net.sf.ehcache.configurationResourceName">/ehcache.xml</prop>
                  <prop key="hibernate.cache.use_second_level_cache">true</prop>
                  <prop key="hibernate.cache.use_query_cache">true</prop>
                  <prop key="hibernate.ejb.interceptor">com.xxx.audit.interceptor.AuditLogInterceptor</prop>                          
            </props>
        </property>     

    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
        p:entityManagerFactory-ref="entityManagerFactory" />

实现EmptyInterceptor的审计日志拦截器:

public class AuditLogInterceptor extends EmptyInterceptor {

    public AuditLogInterceptor() {

    }

    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException {
        //My code for audit logging
        return false;
    }
    @Override
    public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
        //My code for audit logging
        return false;
    }

    @Override
    public void postFlush(Iterator iterator) throws CallbackException {
        //My code for audit logging
        return false;
    }
}

我的服务方法如下所示:

@Service("mySerivceImpl")
    public class MySerivceImpl{

        @Transactional(readOnly = true, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
        public void saveEntity(EntityVO entityVO) {

        }
    }   

请注意,我使用 @Transactional 注释了服务方法。

每当调用此方法时,我会在AuditLogInterceptor中捕获旧的和新的实体值,并尝试使用HistoryDAO将它们保存到我的History表中。

但是在使用AuditDAO在AuditLogInterceptor中保存审计数据时,我遇到了问题:

Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query
        at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:96)
        at com.adp.evolution.dao.audit.AuditDaoImpl.saveAuditData(AuditDaoImpl.java:436)
        at sun.reflect.GeneratedMethodAccessor759.invoke(Unknown Source)

即使我在事务中(即存在服务方法),为什么这个AuditLogInterceptor需要另一个事务?有什么想法吗?

0 个答案:

没有答案