Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在jpa侦听器中获取实体管理器或事务_Java_Hibernate_Jpa_Jpa 2.0_Jboss7.x - Fatal编程技术网

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

Java 如何在jpa侦听器中获取实体管理器或事务,java,hibernate,jpa,jpa-2.0,jboss7.x,Java,Hibernate,Jpa,Jpa 2.0,Jboss7.x,我使用Hibernate事件监听器,如PostDeleteEventListener、PostInsertEventListener、PostUpdateEventListener在插入、删除和更新期间执行一些操作。现在我想使用JPA listener来实现这一点,因为如果我想从Hibernate迁移到任何其他JPA提供程序,我的listener应该可以工作。Hibernate listener为我提供了事件,我可以从中获取事务并检查其是否已提交或回滚。JPA侦听器仅为我提供实体对象。现在,如何

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

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

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

    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
    }
    
  • 通过使用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>
    

    从JPA 2.0开始不支持此功能

    在JPA2.1(计划在JavaEE7中使用)中,持久性提供程序将在托管环境(如JBoss应用服务器)中将实体侦听器视为CDIBean。从第96页的

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

    因此,在JPA2.1中,如果您创建了一个提供EntityManager的CDI生产者(只需将@PersistenceContext字段注释为@products),您就可以将EntityManager@Inject注入到侦听器中


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

    在我的例子中,我使用以下代码:

    ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext();
    auditLogService = (AuditLogService) ctx.getBean("auditLogService");
    
    这对我很有效

    此应用程序的代码可从以下网址下载:


    我希望这能对您有所帮助。

    我的问题是如何在可用的ReceditListener Classis中获取entityManager。我有同样的问题,这应该被称为“答案”,但明确的答案(对于一般情况)是,通过JNDI查找获取entityManager,但要使用的特定绑定是特定于容器的(JBoss、Glassfish、Weblogic等)