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

时间:2018-11-16 16:50:03

标签: spring hibernate jpa transactions

我针对特定问题创建了多个类似的主题,但让我总结一下我在全球范围内面临的问题:

目标

需要拦截在Spring 4.1.5,Hibernate 4.3.8中编写的应用程序中的所有插入/更新/删除数据库事务。该应用程序使用所有样式的Hibernate使用方式:

  • 通过会话基于对象,例如sessionFactory.getCurrentSession().saveOrUpdate(obj);
  • HQL executeUpdate,例如Query q = "update Obj ..."; q.executeUpdate();
  • 标准API,例如Criteria q = sessionFactory.getCurentSession().createCriteria(..); q.list();

可能的方法

  • 拦截器:实施拦截器。

public class MyInterceptor extends EmptyInterceptor {..}

覆盖(1)事务级方法或(2)特定操作方法。

交易级别:

@Override
    public void afterTransactionBegin(Transaction tx) {                 
        super.afterTransactionBegin(tx);            
    }

特定操作级别

@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);
}
  • EventListener :实现PreUpdateEventListenerPreInsertEventListener并注册。

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

问题

  • EventListenerInterceptor方法都不会拦截 HQL executeUpdate()。但是我们在应用程序中有很多实例。其他一些用户已确认:

https://forum.hibernate.org/viewtopic.php?f=1&t=1012054

https://coderanch.com/t/669945/java/Hibernate-interceptor-working-hibernate-query

似乎问题在于EventListener/Interceptor仅与Session一起使用。但是 HQL executeUpdate 位于Query对象上,而不是Session上。

  • 也不能使用afterTransactionBegin(Transaction tx)的事务级拦截器方法。原因是,我无法区分“只读选择事务”与“写入事务”。 tx不会告诉我我是在readOnly=false还是readOnly=true交易中。因此,afterTransactionBegin替代将针对所有交易触发,我需要将其限制为非只读(插入,更新,删除)。

@Transactional(readOnly = false) @Transactional(readOnly = true)

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

0 个答案:

没有答案