我针对特定问题创建了多个类似的主题,但让我总结一下我在全球范围内面临的问题:
目标
需要拦截在Spring 4.1.5,Hibernate 4.3.8中编写的应用程序中的所有插入/更新/删除数据库事务。该应用程序使用所有样式的Hibernate使用方式:
sessionFactory.getCurrentSession().saveOrUpdate(obj);
Query q = "update Obj ..."; q.executeUpdate();
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 :实现PreUpdateEventListener
,PreInsertEventListener
并注册。
@Component
public class HibernateSaveUpdateEventListener implements PreUpdateEventListener, PreInsertEventListener {
@Override
public boolean onPreInsert(PreInsertEvent arg0) {
//...
}
@Override
public boolean onPreUpdate(PreUpdateEvent arg0) {
//...
}
}
问题
EventListener
和Interceptor
方法都不会拦截 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应用程序,是否有一种解决方案可以全面拦截插入/更新/删除?