jLuger.de - ejbPostCreate vs PostPersist

As you may know from previous entries I'm on a project that migrates from EJB 2.1 to EJB 3.0. A co-worker has the glorious task to migrate the Entity Beans from EJB 2.1 to POJOs with JPA-Annotations and DAOs (Data Access Objects). The old application made use of ejbPostCreate to attach child data to persisted objects.

So he searched the JPA javadoc and found the annotation PostPersist. When the DAO is an EntityListener for the Entity, the method annotated with PostPersist is called after the INSERT-Statement was sent to the database. So my co-worker put the code that was in ejbPostCreate into a method annotated with PostPersist. This code attaches some child nodes and then calls a persist method again. When running the unit test there was always the following exception:
org.hibernate.AssertionFailure: collection [...] was not processed by flush()

After some trial and error we've ended up to move all code from the method annotated with Post Persist to the persist method. And finally the unit test worked. But what was causing the exception? Googling after it showed only some hibernate bug entries. The hibernate version we use has them all fixed.

The solution to the problem is buried in the hibernate documentation. In http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/listeners.html there is the following sentence:
»A callback method must not invoke EntityManager or Query methods!«

A method annotated with PostPersist is a callback method and to the saving of the object we needed an invocation of the EntityManager. But instead of throwing an Exception on access of the EntityManager Hibernate continued until it hit an internal error. An internal error with a message that was pretty misleading.