rhinds
rhinds

Reputation: 10043

Is it possible to persist new Entities in a @Pre/PostPersist Listener?

I am trying to setup my hibernate application to persist a new Notification entity everytime an Activity Entity is created - at the moment, everything i have tried the Notification just fails to persist silently (no errors in the logs but sql is never executed).

Can anyone confirm that it is even possible to persist additional entities in the Hibernate pre/postPersist listeners?

I have read in the documentation:

A callback method must not invoke EntityManager or Query methods!

But I have read several other discussion threads that seem to indicate that it is possible.

For reference, the two approaches I have attempted are:

  1. @PrePersist method - setting a cascade.ALL relationship between Activity and Notification, and in the PrePersist method simply creating a new Notification and linking it to the Activity being created in a hope that the Notification would be persisted.

  2. @PostPersist method - using @Configurable and a ListenerClass, wiring in a service and creating a new Notification entity and then explicitly calling the entityManger persist

Can someone confirm what I am trying is possible?

Upvotes: 12

Views: 7323

Answers (2)

Mr.J4mes
Mr.J4mes

Reputation: 9266

Why do you have to persist Notification in @PrePersist or @PostPersist function? The following code should persist both entities:

@Entity
public class Activity implements Serializable {
   @OneToOne(cascade={CascadeType.PERSIST})
   private Notification notification;
}

@Entity
public class Notification implements Serializable { }

@Stateless
public class MrBean implements MrBeanInterface {
   @PersistenceContext()
   private EntityManager em;

   public void persistActivity() {
      Activity act = new Activity();
      act.setNotification(new Notification());
      em.persist(act);
   }
}

UPDATE: you can try creating the link inside the Activity's constructor like this:

@Entity
public class Activity implements Serializable {
   @OneToOne(cascade={CascadeType.PERSIST})
   private Notification notification;

   public Activity() {
      this.notification = new Notification();
   }
}

@Entity
public class Notification implements Serializable { }

@Stateless
public class MrBean implements MrBeanInterface {
   @PersistenceContext()
   private EntityManager em;

   public void persistActivity() {
      Activity act = new Activity();
      em.persist(act);
   }
}

One thing to note is that I think you cannot use @PostPersist. To be more precise, you must link Notification to Activity before persisting Activity in order for cascade={CascadeType.PERSIST} to work.

Upvotes: 2

tscho
tscho

Reputation: 2054

You can persist additional entities in Hibernate event listeners (insert, update, flush, etc) with the StatelessSession interface. But I don't know if this is also possible with strict JPA only code (EntityManagerFactory and EntityManager).

Upvotes: 2

Related Questions