gen*_* b. 6 spring hibernate jpa transactions
我创建了几个关于特定问题的类似线程,但让我总结一下我在全球范围内面临的问题:
目标
需要拦截使用 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);
}
Run Code Online (Sandbox Code Playgroud)
具体行动级别:
@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);
}
Run Code Online (Sandbox Code Playgroud)
EventListener:实现 aPreUpdateEventListener并PreInsertEventListener注册它。
@Component
public class HibernateSaveUpdateEventListener implements PreUpdateEventListener, PreInsertEventListener {
@Override
public boolean onPreInsert(PreInsertEvent arg0) {
//...
}
@Override
public boolean onPreUpdate(PreUpdateEvent arg0) {
//...
}
}
Run Code Online (Sandbox Code Playgroud)问题
EventListener或方法都不会Interceptor拦截HQLexecuteUpdate()。但我们的应用程序中有很多这样的例子。其他一些用户已经证实:https://forum.hibernate.org/viewtopic.php?f=1&t=1012054
https://coderanch.com/t/669945/java/Hibernate-interceptor-working-hibernate-query
似乎问题是EventListener/Interceptor只能与Session. 但HQLexecuteUpdate是在Query对象上,而不是Session.
afterTransactionBegin(Transaction tx)其中任何一个的事务级拦截器方法。原因是,我无法区分只读选择事务和写入事务。tx不告诉我我是否处于readOnly=false交易中readOnly=true。因此,覆盖将对所有afterTransactionBegin事务触发,我需要将其限制为非只读事务(插入、更新、删除)。@Transactional(readOnly = false)
@Transactional(readOnly = true)
那么对于同时使用对象操作和HQL操作的Hibernate应用程序来说,有没有一种解决方案可以全面拦截Insert/Update/Delete呢?
有一种简单的方法可以使用Spring 级别的事务侦听器检查只读/非只读事务,这将包括外部 SQL/HQL(非实体)。在 Spring 级别,而不是 Hibernate,有一个名为的方法TransactionSynchronizationManager.isCurrentTransactionReadOnly()告诉我们是否处于我们正在拦截的只读事务中。可以从以下实现中调用它,TransactionSynchronization该实现使用切入点来拦截所有@Before @TransactionalSpring 处理。
@Component
@Aspect
public class TransactionSynchronizationAspect implements TransactionSynchronization {
@Before("@annotation(org.springframework.transaction.annotation.Transactional)")
public void registerTransactionSynchronization() {
boolean isReadOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
if (!isReadOnly) {
// ... logic goes here...
}
// Continue
TransactionSynchronizationManager.registerSynchronization(this);
}
@Override
public void afterCompletion(int status) {
// No custom code here
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1568 次 |
| 最近记录: |