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

时间:2012-10-18 09:44:11

标签: java hibernate jpa jpa-2.0 jboss7.x

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

3 个答案:

答案 0 :(得分:7)

从JPA 2.0开始不支持。

在JPA 2.1(原定于Java EE 7中)中,持久性提供程序将在托管环境(例如JBoss应用程序服务器)中将实体侦听器视为CDI bean。来自Proposed Final Draft of the JPA 2.1 spec,第96页:

  

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

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

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

答案 1 :(得分:1)

就我而言,我使用此代码:

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

这对我很有用。

可以在https://bitbucket.org/macielbombonato/apolo

下载此应用程序的代码

我希望这可以帮到你。

答案 2 :(得分:-2)

您可以使用以下两种方式在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配置文件。

  3. 最后,可以使用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>