有沒有辦法在之後收聽事件* * AfterTransactionCompletion(2次後)?Hibernate afterAfterTransactionCompletion攔截器
我工作的一個應用程序,用戶可以修改的實體並保存:
tx.begin();
entity.name = "Archimede";
em.merge(entity);
tx.commit();
我想攔截的承諾,而「正確」的實體。假設:如果name.equal(「Archimede」),那麼攔截器應該改變surname =「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()。
我想在這裏有一個攔截器方法,所以以前的代碼應該沒有任何問題。
任何人都知道一種方式?或者我的方法錯了? (任何更好的?)
爲什麼你不使用@PrePersist註釋? – willome
也在@PrePersist我不應該使用EntityManager或事務,並且我想只在事務實際提交時(而不是在回滾時)「糾正」實體。此外,交易不應該依賴於「更正」(如果更正失敗,只是更正交易失敗,而不是第一次)。他們應該是兩個分開的交易。 – lelmarir
爲什麼我有看到不安全的併發代碼的感覺?將實體作爲實例字段使其變得糟糕。你怎麼看 ? –