我在使用手动交易时插入/更新3个表。我想在事务提交后立即插入历史表。这意味着有3 em.persist
个动作(对于每个表),并且只有在提交它们之后我才想调用一个方法。
这是我的代码:
@Resource
private EJBContext context;
public void save(Object obj)
{
try
{
transaction = context.getUserTransaction();
transaction.begin();
em.persist(obj);
sb2.save(obj); //persist in sb2
sb3.save(obj); //persist in sb2
transaction.commit();
}
catch (Exception exp)
{
transaction.rollback();
}
}
有任何类型的post commit方法吗? 如何在提交后调用方法,而不是在持久化之后?
答案 0 :(得分:0)
JPA不提供此类事件,但EclipseLink通过SessionEventListener API提供扩展事件。
http://eclipse.org/eclipselink/documentation/2.5/jpa/extensions/p_session_event_listener.htm
您还可以考虑容器JTA事件。
答案 1 :(得分:0)
您可以使用TransactionSynchronizationRegistry
注册要在事务完成后执行的回调:
public class MyListener {
// if you can't inject it with @Resource, you'll have to fetch it from JNDI
@Resource
private javax.transaction.TransactionSynchronizationRegistry registry;
@PostUpdate
public void postUpdate(final Object entity) {
registry.registerInterposedSynchronization(new Synchronization() {
public void beforeCompletion() {}
public void afterCompletion(int status) {
if (status == javax.transaction.Status.STATUS_COMMITTED) {
// Do something with your entity
}
}
});
}
}
然后使用@EntityListeners(MyListener.class)
为您的实体添加注释(或将其添加到您的orm.xml
中)。
答案 2 :(得分:0)
如果您在JPA 2.2 + CDI + JTA环境中,则可以利用在指定的事务阶段可以观察到的CDI事件。
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface EntityEvent {}
public class MyListener {
@Inject
@EntityEvent
private Event<Object> event;
@PostUpdate
public void postUpdate(Object entity) {
event.fire(entity);
}
}
public class MyObserver {
public void afterCommit(@Observes(during = TransactionPhase.AFTER_SUCCESS) @EntityEvent Object entity) {
// do something...
}
}
@EntityListeners(MyListener.class)
public class MyEntity {}