How to comprehensively intercept Insert/Update/Delete DB Transactions in a Hibernate 4 application

帅比萌擦擦* 提交于 2019-12-22 22:16:23

问题


I created several similar threads about particular issues, but let me summarize the problem I'm facing more globally:

GOAL

Need to intercept all Insert/Update/Delete DB Transactions in an application written in Spring 4.1.5, Hibernate 4.3.8. The app uses all styles of Hibernate usage:

  • Object-based through Session, e.g. sessionFactory.getCurrentSession().saveOrUpdate(obj);
  • HQL executeUpdate, e.g. Query q = "update Obj ..."; q.executeUpdate();
  • Criteria API, e.g. Criteria q = sessionFactory.getCurentSession().createCriteria(..); q.list();

Possible Approaches

  • Interceptor: Implement an Interceptor.

public class MyInterceptor extends EmptyInterceptor {..}

Override either (1) Transaction-level methods or (2) specific action methods.

Transaction-level:

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

Specific action level:

@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: Implement a PreUpdateEventListener, PreInsertEventListener and register it.

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

Problems

  • Neither the EventListener nor Interceptor approach intercepts HQL executeUpdate(). But we have many instances of that in the app. Some other users have confirmed that:

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

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

Seems like the issue is that EventListener/Interceptor only work with a Session. But HQL executeUpdate is on the Query object, not the Session.

  • Can't use the Transaction-level Interceptor approach of afterTransactionBegin(Transaction tx) either. The reason is, I can't distinguish Read-Only Select Transactions from Write Transactions. tx doesn't tell me whether I'm in a readOnly=false or readOnly=true transaction. So the afterTransactionBegin override will fire for all transactions, and I need to limit it non-Read-Only ones only (Insert, Update, Delete).

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

So is there a solution to comprehensively intercept Insert/Update/Delete for a Hibernate app that uses both object operations and HQL operations?

来源:https://stackoverflow.com/questions/53342179/how-to-comprehensively-intercept-insert-update-delete-db-transactions-in-a-hiber

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!