Spring 如何在Hibernate 4应用程序中全面拦截插入/更新/删除DB事务

Spring 如何在Hibernate 4应用程序中全面拦截插入/更新/删除DB事务,spring,hibernate,jpa,transactions,Spring,Hibernate,Jpa,Transactions,我创建了几个关于特定问题的类似线程,但让我总结一下我在全球面临的问题: 目标 需要拦截Spring 4.1.5、Hibernate 4.3.8中编写的应用程序中的所有插入/更新/删除DB事务。应用程序使用所有类型的Hibernate使用: 通过会话基于对象,例如sessionFactory.getCurrentSession().saveOrUpdate(obj) HQL executeUpdate,例如查询q=“更新对象…”;q、 executeUpdate() 标准API,例如标准q=se

我创建了几个关于特定问题的类似线程,但让我总结一下我在全球面临的问题:

目标

需要拦截Spring 4.1.5、Hibernate 4.3.8中编写的应用程序中的所有插入/更新/删除DB事务。应用程序使用所有类型的Hibernate使用:

  • 通过会话基于对象,例如
    sessionFactory.getCurrentSession().saveOrUpdate(obj)
  • HQL executeUpdate,例如查询q=“更新对象…”;q、 executeUpdate()
  • 标准API,例如标准q=sessionFactory.getCurentSession().createCriteria(…);q、 list()
可能的方法

  • 拦截器:实现拦截器
公共类MyInterceptor扩展了EmptyInterceptor{..}

重写(1)事务级方法或(2)特定操作方法

事务级别:

具体行动级别:

  • EventListener:实现一个
    预更新EventListener
    预插入EventListener
    ,并注册它

    @Component
    public class HibernateSaveUpdateEventListener implements PreUpdateEventListener, PreInsertEventListener  {
        @Override
        public boolean onPreInsert(PreInsertEvent arg0) {
            //...
        }
        @Override
        public boolean onPreUpdate(PreUpdateEvent arg0) {
          //...
        }
    }
    
问题

  • EventListener
    Interceptor
    方法都不会拦截HQL executeUpdate()。但我们在应用程序中有很多这样的例子。其他一些用户已确认:

问题似乎在于
EventListener/Interceptor
仅适用于
会话
。但是HQL executeUpdate
Query
对象上,而不是在
会话上

  • 也不能使用
    afterTransactionBegin(Transaction tx)
    的事务级拦截器方法。原因是,我无法区分只读选择事务和写入事务
    tx
    不会告诉我是否处于
    readOnly=false
    readOnly=true
    事务中。因此,
    afterTransactionBegin
    覆盖将为所有事务触发,我需要将其限制为非只读事务(插入、更新、删除)
@Transactional(readOnly=false)
@事务性(只读=真)

对于同时使用对象操作和HQL操作的Hibernate应用程序,是否有一种全面拦截插入/更新/删除的解决方案?

使用and可能是另一种可能的方法
@Override
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
    return super.onSave(entity, id, state, propertyNames, types);
}

@Override
public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
    super.onDelete(entity, id, state, propertyNames, types);
}
@Component
public class HibernateSaveUpdateEventListener implements PreUpdateEventListener, PreInsertEventListener  {
    @Override
    public boolean onPreInsert(PreInsertEvent arg0) {
        //...
    }
    @Override
    public boolean onPreUpdate(PreUpdateEvent arg0) {
      //...
    }
}