jpa @postpersist @postupdate 仅在事务提交后
Posted
技术标签:
【中文标题】jpa @postpersist @postupdate 仅在事务提交后【英文标题】:jpa @postpersist @postupdate only after transaction commit 【发布时间】:2013-07-07 11:05:34 【问题描述】:我在使用手动事务时插入/更新 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 方法? 如何在提交之后而不是在持久化之后调用方法?
【问题讨论】:
【参考方案1】:您可以使用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
)。
【讨论】:
不错。您可以在 J2SE 应用程序中注册类似的处理程序吗?【参考方案2】:如果您处于 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
【讨论】:
【参考方案3】:JPA 不提供此类事件,但 EclipseLink 通过 SessionEventListener API 提供扩展事件。
http://eclipse.org/eclipselink/documentation/2.5/jpa/extensions/p_session_event_listener.htm
您也可以考虑容器 JTA 事件。
【讨论】:
以上是关于jpa @postpersist @postupdate 仅在事务提交后的主要内容,如果未能解决你的问题,请参考以下文章
使用 JPA 2.1、EclipseLink、JSF 2.0 的日志表