[英]Hibernate afterAfterTransactionCompletion interceptor
有没有办法在 * AfterTransactionCompletion之后(2次之后)监听事件*?
我正在开发一个应用程序,用户可以在其中修改实体并保存它:
tx.begin();
entity.name = "Archimede";
em.merge(entity);
tx.commit();
我想拦截提交,并“更正”该实体。 假设:如果name.equal(“ Archimede”),则拦截器应更改姓氏=“ Pitagorico”。
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
changedEntities.add(entity); //register all changing entities
}
public void afterTransactionCompletion(Transaction tx) {
for(T entity : changedEntities) {
if(entity.name.euqual("Archimede")) {
em.getTransaction().begin();
entity.surname = "Pitagorico";
sendNotificationToUser();
em.getTransaction().commit();
}
}
}
问题是不允许在拦截器中使用entityManager或事务,并且这样会失败:
org.hibernate.TransactionException: reuse of Transaction instances not supported
有罪的是这里(org.hibernate.engine.transaction.spi.AbstractTransactionImpl):
@Override
public void commit() throws HibernateException {
if ( localStatus != LocalStatus.ACTIVE ) {
throw new TransactionException( "Transaction not successfully started" );
}
LOG.debug( "committing" );
beforeTransactionCommit();
try {
doCommit();
localStatus = LocalStatus.COMMITTED;
afterTransactionCompletion( Status.STATUS_COMMITTED ); //<-------
}
catch ( Exception e ) {
localStatus = LocalStatus.FAILED_COMMIT;
afterTransactionCompletion( Status.STATUS_UNKNOWN );
throw new TransactionException( "commit failed", e );
}
finally {
invalidate(); //<-------
afterAfterCompletion(); //<-------
}
}
拦截器由afterTransactionCompletion(Status.STATUS_COMMITTED)调用; ,但这是在invalidate()之前; ,并且交易仍处于COMMIT状态。 仅在下一行中,它调用afterAfterCompletion();,此时事务应该有效并且可以使用.begin() 。
我想在这里有一个拦截器方法,所以前面的代码应该没有任何问题。
有人知道吗? 还是我的方法不对? (更好的吗?)
我将使用一些AOP并使用@Transactions
例如:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public MyEntity doSaveService(MyEntity myentity){
em.merge(myentity); // not required but easier to read
em.flush(); //not sure if you need it
}
在此合并方法上添加一些AOP(根据需要添加一些注释或XML声明)
@Transactional(propagation = Propagation.REQUIRES_NEW)
protected Object postMergeProcess(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
MyEntity myEntityBeforeMerge = (MyEntity ) proceedingJoinPoint.getArgs()[0];
MyEntity myEntityAfterMerge = (MyEntity ) proceedingJoinPoint.proceed();
myEntityAfterMerge.setWhatever("xxx");
em.merge();
}
XML:
<aop:config>
<aop:aspect ref="">
<aop:pointcut id="mergePointCut" expression="execution(* x.y.z.EntityService.merge(..))" />
<aop:around method="postMergeProcess" pointcut-ref="mergePointCut" />
</aop:aspect>
</aop:config>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.