Search code examples
hibernategrailsjpadatasourcejavassist

Hibernate JPA conflict in Grails 2.4.4


I've been upgrading a Grails 1.3.7 application to 2.4.4, using Hibernate 3 due to Spring Security being incompatible with the hibernate4 plugin, and have run into issues with this kind of stacktrace at runtime:

java.lang.ClassCastException: com.xxxxxx.grails.domain.WorkflowStepDescription_$$_javassist_1 cannot be cast to javassist.util.proxy.ProxyObject 
at org.codehaus.groovy.grails.orm.hibernate.proxy.GroovyAwareJavassistLazyInitializer.createProxyInstance(GroovyAwareJavassistLazyInitializer.java:107)
at org.codehaus.groovy.grails.orm.hibernate.proxy.GroovyAwareJavassistLazyInitializer.getProxy(GroovyAwareJavassistLazyInitializer.java:134)
at org.codehaus.groovy.grails.orm.hibernate.proxy.GroovyAwareJavassistProxyFactory.getProxy(GroovyAwareJavassistProxyFactory.java:64) 
at org.codehaus.groovy.grails.orm.hibernate.persister.entity.GroovyAwareSingleTableEntityPersister.createProxy(GroovyAwareSingleTableEntityPersister.java:49)
at org.hibernate.event.def.DefaultLoadEventListener.createProxyIfNecessary(DefaultLoadEventListener.java:360) 
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:281) 
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152) 
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090) 
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:1038) 
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:630) 
at org.hibernate.type.EntityType.resolve(EntityType.java:438) 
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139) 
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982) 
at org.hibernate.loader.Loader.doQuery(Loader.java:857) 
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274) 
at org.hibernate.loader.Loader.doList(Loader.java:2542) 
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276) 
at org.hibernate.loader.Loader.list(Loader.java:2271) 
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119) 
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716) 
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347) 

Searching around indicates that this is due to conflicts with Javassist versions, and sure enough, I have two different versions in my built JAR:

hibernate-jpa-2.0-api-1.0.1.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar

Looking at grails dependency-report, it looks like the dependency on 2.1 is coming from Grails itself:

The one from Hibernate 3.6.10.18:


    +--- org.grails.plugins:hibernate:3.6.10.18
    |    \--- org.hibernate:hibernate-entitymanager:3.6.10.Final
    |         \--- org.hibernate:hibernate-core:3.6.10.Final
    |              \--- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final

The one from Grails 2.4.4:


    +--- org.grails:grails-plugin-datasource:2.4.4
    |    \--- org.grails:grails-core:2.4.4
    |         \--- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final

I know that Grails 2.4.4 has the option of using Hibernate 3... can I avoid this conflict of dependencies, perhaps by downgrading the datasource plugin?


Solution

  • Okay, this is so convoluted that I doubt it'll help anybody else, but I solved it - I noticed that this exception only happened on one particular domain class. After a lot of trial and error, I found it was because the class had a property called "handler", which I can only assume is conflicted with a method in later versions of javassist. I changed that to "actionHandler", and the errors are gone.

    The two JAR versions are no doubt still a problem, but they were a red herring on this issue. Check your domain class property names for anything suspicious!