如何在jpa侦听器中获取实体管理器或事务

我正在使用像PostDeleteEventListener, PostInsertEventListener, PostUpdateEventListener这样的Hibernate事件监听PostDeleteEventListener, PostInsertEventListener, PostUpdateEventListener来执行插入,删除和更新期间的一些操作。 现在我想使用JPA监听器来执行此操作,因为如果我想从Hibernate转移到任何其他JPA提供程序,我的监听器应该工作。 Hibernate监听器为我提供了event ,我可以从中获取事务并检查其是否已提交或回滚。 JPA监听器只为我提供实体对象。 现在我如何在JPA监听器中获取事务或会话或实体管理器? 提前致谢!! 我使用Jboss作为我的CMT。

从JPA 2.0开始不支持此function。

在JPA 2.1(定义为Java EE 7)中,持久性提供程序将在托管环境(例如JBoss应用程序服务器)中将实体侦听器视为CDI bean。 根据JPA 2.1规范的拟议最终草案 ,第96页:

当包含存档是bean存档时,Java EE环境中的实体监听器类通过上下文和dependency injectionAPI(CDI)[10]支持dependency injection。 使用CDI注入的实体侦听器类还可以定义使用PostConstruct和PreDestroy注释注释的生命周期回调方法。 在注入发生之后和实体侦听器实例分别被销毁之前,将调用这些方法

因此,在JPA 2.1中,如果您创建一个提供EntityManager的CDI生成器(只需使用@Produces注释@PersistenceContext字段),您就可以将EntityManager注入到侦听器中。

与此同时,我不知道任何干净或愉快的解决方法。 我能想到的“最糟糕的”事情是将EntityManager配置为绑定在JNDI中,然后通过侦听器内的JNDI查找来获取它。

在我的情况下,我正在使用此代码:

 ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext(); auditLogService = (AuditLogService) ctx.getBean("auditLogService"); 

这对我很有用。

该应用程序的代码可从https://bitbucket.org/macielbombonato/apolo下载

我希望这可以帮到你。

您可以使用以下两种方式在JPA中使用所有前/后加载,插入,更新或删除侦听器:

  1. 通过使用注释。 使用Listener的一个简单示例可能是实体有一个瞬态变量,需要在实体被持久化,更新或加载后填充,例如:

     public class AvailableCreditListener { @PostLoad @PostPersist @PostUpdate public void calculateAvailableCredit(Account account) { account.setAvailableCredit( account.getBalance().add( account.getOverdraftLimit())); } } 

    实体类将使用@EntityListeners进行注释:

     @EntityListeners({AvailableCreditListener.class}) public class Account extends BaseEntity { private BigDecimal balance; private BigDecimal overdraftLimit; @Transient private BigDecimal availableCredit; // getters and setters } 
  2. 通过使用persistence.xml配置文件。

最后,可以使用XMl映射文件而不是注释,并与应用程序一起部署以指定默认侦听器。 (此映射文件由persistence.xml文件引用。)但是,如果实体不想使用默认侦听器,则可以使用@ExcludeDefaultListeners批注。

 @ExcludeDefaultListeners @Entity public class Account extends BaseEntity { .... } 

在你的persistence.xml中: