Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 379
rhinds Avatar asked Dec 26 '11 21:12

rhinds


People also ask

How does @PrePersist work?

The @PrePersist annotation is used to configure a callback for pre-persist(pre-insert) events of the entity. In other words, it is used to annotate model methods to indicate that the method should be called before the entity is inserted (persisted) into the database.

What is an entity listener?

An entity listener is a stateless class with a no-arg constructor. An entity listener is defined by annotating the entity class with the @EntityListeners annotation: @Entity. @EntityListeners(class=Audit. class)

What callback will be invoked after saving an entity to the database?

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.


2 Answers

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.

like image 72
Mr.J4mes Avatar answered Nov 11 '22 19:11

Mr.J4mes


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).

like image 21
tscho Avatar answered Nov 11 '22 21:11

tscho