【问题标题】:JPA @PostPersist usageJPA @PostPersist 用法
【发布时间】:2013-03-20 02:21:17
【问题描述】:

我有一个持久化实体对象的方法 persistData()。我有另一种方法 findData() 对同一实体类执行 find() 操作以获取持久的主键值。当我在实体类的@PostPersist 中调用 findData() 时,我得到一个空指针异常。这让我想到了几个问题:

  1. 为什么会出现空指针错误?
  2. @PostPersist 在现实中有什么用?
  3. 实际何时调用@Postpersist?提交后、提交期间还是提交前?

任何进一步的见解也将不胜感激。请在下面找到相关代码和堆栈跟踪:

public void persistData(){
        EntityManagerFactory fac= Persistence.createEntityManagerFactory("test");
        EntityManager man = fac.createEntityManager();

        Employee e = new Employee();
        e.setEmpId(500);
        e.setEmpName("Emp5");
        e.setSalary(5000);
        man.getTransaction().begin();
        man.persist(e);
        man.getTransaction().commit();
        man.close();

    }



public void findData(){
        EntityManagerFactory fac= Persistence.createEntityManagerFactory("test");
        EntityManager man = fac.createEntityManager();

        Employee e=man.find(Employee.class, 500);
        System.out.println(e.getEmpName());
        man.close();    
    }

@PostPersist
public void getData(){
    new Service().findData();
}

堆栈跟踪(部分):

Exception in thread "main" javax.persistence.RollbackException: java.lang.NullPointerException
    at oracle.toplink.essentials.internal.ejb.cmp3.transaction.base.EntityTransactionImpl.commit(EntityTransactionImpl.java:120)
    at oracle.toplink.essentials.internal.ejb.cmp3.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:60)
    at Service.persistData(Service.java:18)
    at Service.main(Service.java:34)
Caused by: java.lang.NullPointerException
    at Service.findData(Service.java:28)
    at Employee.getData(Employee.java:33)

注意:我使用的是 JPA 1.0

【问题讨论】:

  • 发布 postPersist 方法 + stacktrace 它将帮助我们帮助您
  • 你用的是哪个版本的toplink?
  • 行在哪里:Service.java:28
  • 服务:18-man.getTransaction.commit();服务:28 -System.out.println(e.getEmpName()); Employee:33-@PostPersist 的 new Service().findData()

标签: jpa callback lifecycle


【解决方案1】:

回答你的问题1:

(需要代码和堆栈跟踪)

回答你的问题2:

@PostPersist 表示 JPA 回调方法。它允许您通过实体生命周期事件触发一些代码。

一个真实的例子?

假设您有一个 User 表,并且您希望在每次持久化新用户时生成一封确认电子邮件:您可以在 PostPersist 方法中执行此操作。

回答你的问题3:

规范的相关部分在血中。

来自 JPA-2.0 规范:

在实体被持久化或删除后,将为实体调用 PostPersist 和 PostRemove 回调方法。这些回调也将在这些操作级联到的所有实体上调用。 PostPersist 和 PostRemove 方法将分别在数据库插入和删除操作之后被调用。 这些数据库操作可能在调用持久化、合并或删除操作后直接发生,也可能在刷新操作发生后直接发生(可能在事务结束时)。生成的主键值在 PostPersist 方法中可用。

【讨论】:

  • 嗨,我知道@PostPersist 的作用。但我想知道一个真实的例子。此外,规范说“坚持后”。这是否意味着在 commit() 结束之后?
  • 正如它所指定的:它可能直接发生在 persist() 方法返回之后,或者它可能直接发生在 flush() 方法返回之后。所以它似乎取决于你的事务配置(即第一个或第二个行为之间的选择)
【解决方案2】:

我正在使用的@PostPersist 的一个真实例子是—— 我正在创建一个任务管理系统。在这个任务管理系统中,任务被分配给一个代理。但是,在某些情况下,任务没有得到源系统自动分配的代理。在这种情况下,每当任务被持久化并且任务分配引擎侦听该事件并进行处理时,我都会触发一个事件。 我敢肯定还有其他方法可以做同样的事情,但我认为这种异步方式从性能角度使系统更好。

【讨论】:

    猜你喜欢
    • 2011-06-21
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多