January 24, 2012

Hibernate relations and event listeners

1  comments

In my current project I work on a Java EE application with a hibernate backend. The applications supports two databases MSSql and Oracle. The development started with MSSql. One of my tasks was to migrate the application to Oracle. We expected some problems with Spring ACLs which uses SQL instead of OR Mapping. To fix that I just had to write some custom SQL for Oracle. After handling the ACLs I got transaction problems with oracle, we hadn't with MSSql. After some tests and research I found out that to fix this I had to add a entityManager.flush(); to the persist and merge method of our entity manager. I was happy to resolved the issue an started our test suite. Then I run into an exception like this:
Caused by: 
org.hibernate.AssertionFailure: collection [someEntity] was not processed by flush()
I got this exception on our local H2-database on MSSql and Oracle. After some research I found this issue in the hibernate Jira: HHH-2763: Allow initialization during flush In the first place I ignored it because the entry was from 2007. After some more research and some tests I found out that our problem looked similar to the issue reported to hibernate. We had relations and we had listeners in the form of PrePersistCallbacks and PreUpdateCallbacks. I couldn't believe that an issue from 2007 was still not fixed. My next step was to write a test case to reproduce the error. The test case is very domain specific so I can't post it here. I found out that the bug was already fixed in grails. With this knowledge it was easy to came to this solution:
package app.dao;

import org.hibernate.HibernateException;
import org.hibernate.ejb.event.EJB3FlushEventListener;
import org.hibernate.event.EventSource;

/**
 * This file is heavily inspired by the PatchedDefaultFlushEventListener from grails:
 * https://github.com/grails/grails-core/blob/master/grails-hibernate/src/main/groovy/org/codehaus/groovy/grails/orm/hibernate/events/PatchedDefaultFlushEventListener.java
 * 
 * Patches Hibernate to prevent this issue
 * https://hibernate.onjira.com/browse/HHH-2763
 *
 * TODO: Remove this patch when HHH-2763 is resolved
 * 
 */

public class PatchedFlushListener extends EJB3FlushEventListener {

  private static final long serialVersionUID = -6913148400994182443L;
  
  @Override
  protected void performExecutions( EventSource session ) throws HibernateException {
    session.getPersistenceContext().setFlushing( true );
    try {
      super.performExecutions( session );
    } finally {
      session.getPersistenceContext().setFlushing( false );
    }
  }
}
To make this work in our application I had to add this spring configuration to our applicationContext-datasource.xml:

      
        
        
     	
      

The problem occurred with Hibernate 3.6.7.Final which was the latest stable release by the time I run into it. It should be fixed in Hibernate 4.0.0.Final or later which final release was in december.

Tags

Bug, event listener, Grails, Hibernate, Java, Java EE, JPA, MSSql, Oracle, relations, Spring


You may also like

Blog url changed to https

I just changed the url of this blog to https://jensjaeger.com. TLS encryption is now the default for all request to this page. It might be possible that some image links on some articles are hard coded http. If you find such an error it would be nice if you leave me comment so i can

Read More

Format date and time in java with prettytime

Prettytime is a nice java library to format a java Date()s in a nice humanized ago format, like: moments ago 2 minutes ago 13 hours ago 7 months ago 2 years ago Prettytime is localized in over 30 languages. It’s super simple to use Add the dependency to your maven pom: org.ocpsoft.prettytime prettytime 3.2.7.Final or

Read More