9

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

4

3 回答 3

7

从 JPA 2.0 开始不支持此功能。

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

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

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

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

于 2013-02-25T23:26:40.613 回答
1

就我而言,我正在使用以下代码:

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

这对我很有效。

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

我希望这可以帮助你。

于 2015-06-24T05:24:57.317 回答
-3

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

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

    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 中:

<persistence-unit-metadata>
    <persistence-unit-defaults>
      <entity-listeners>
        <entity-listener class="samples.AvailableCreditListener"/>      
      </entity-listeners>
    </persistence-unit-defaults>
  </persistence-unit-metadata>
于 2012-11-06T12:57:38.947 回答