JPA @PostPersist用法

时间:2013-03-29 11:27:08

标签: jpa callback lifecycle

我有一个持久化实体对象的方法persistData()。我有另一个方法findData(),它对持久存在的主键值在同一实体类上执行find()操作。当我在实体类的@PostPersist中调用findData()时,我得到一个空指针异常。这引起了我的一些问题:

  1. 为什么会出现空指针错误?
  2. @PostPersist在现实中的用途是什么?
  3. @Postpersist什么时候被称为?提交后,提交期间还是提交之前?
  4. 任何进一步的见解也将不胜感激。请在下面找到相关代码和堆栈跟踪:

    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

2 个答案:

答案 0 :(得分:4)

回答你的问题1:

(需要代码和堆栈跟踪)

回答你的问题2:

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

一个真实的例子?

假设您有一个用户表,并且每次持久保存新用户时都要生成确认电子邮件:您可以使用 PostPersist 方法执行此操作。

回答你的问题3:

规范的相关部分是盲目的。

来自JPA-2.0规范:

  

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

答案 1 :(得分:0)

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