5

I have a method persistData() which persists an entity object. I have another method findData() which performs find() operation on the same entity class for the primary key value which was persisted. When I call the findData() in the @PostPersist of the entity class, I get a null pointer exception. This has raised a few questions in my mind:

  1. Why is it giving a null pointer error?
  2. What is the use of @PostPersist in reality?
  3. When is a @Postpersist actually called? After commit, during commit or before commit?

Any further insights would also be appreciated. Please find the relevant code and stacktrace below:

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();
}

Stack Trace ( Partial ):

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)

Note: I am using JPA 1.0

codingsplash
  • 4,785
  • 12
  • 51
  • 90

2 Answers2

6

To answer your question 1:

(need the code and the stacktrace)

To answer your question 2:

The @PostPersist indicate a JPA callback method. It allows you to trigger some code through the entity life-cycle events.

A real life example ?

Assume you have a User table and you want to generate a confirmation email every time a new User is persisted: you can do it in a PostPersist method.

To answer your question 3:

The relevant part of specs are in blod.

From JPA-2.0 specs:

The PostPersist and PostRemove callback methods are invoked for an entity after the entity has been made persistent or removed. These callbacks will also be invoked on all entities to which these operations are cascaded. The PostPersist and PostRemove methods will be invoked after the database insert and delete operations respectively. These database operations may occur directly after the persist, merge, or remove operations have been invoked or they may occur directly after a flush operation has occurred (which may be at the end of the transaction). Generated primary key values are available in the PostPersist method.

ben75
  • 29,217
  • 10
  • 88
  • 134
  • 1
    Hi, I know what a @PostPersist does. But I wanted to know a real life example of it. Also, the spec says "after persist". Does that mean after commit() ends? – codingsplash Mar 29 '13 at 12:55
  • As it is specified : it MAY occurs directly after the persist() method return or it MAY occurs directly after the flush() method returns. So it seems that it depends on your transaction configuration (i.e. the choice between first or second behavior) – ben75 Mar 29 '13 at 13:01
  • 1
    Just want to clarify the last part - The spec was referring to PostPersist being executed as part of the flush, out side of the application's control, and not being done 'after' flush/commit. Any exception thrown within lifecycle events like PostPersist and PostUpdate are required to cause the transaction to rollback - which means they are still executed within the context of the current transaction, before it is committed. The spec was just mentioning that the statement, and so post lifecycle event, might happen after the persist/merge call, but before the process returns from a transaction. – Chris Mar 09 '22 at 19:57
0

One real life example of @PostPersist which i am using is -- I am creating a task management system. In this task management system, task is assigned to an agent. However, there can be scenarios when task does not get an agent is assigned automatically by source system. In this scenario, i am triggering an event whenever an task is persisted and a task allocation engine listens to that event and does its processing. I am sure there are other ways of doing the same thing, but i thought this Async way makes system better from performance perspective.

Samir Baid
  • 1,128
  • 2
  • 11
  • 20