I recently faced a weird problem when using Grails and a domain class hierarchy that contained abstract classes, let’s say:
abstract class A { ...} abstract class B extends C { ...} class C extends A { ...} class D extends B { ...}
So the problem was that a certain instance of the class D, in a certain context (i.e. given the same instance, it didn’t show the problem always, but actually only when used in a certain gsp), was saying that its class was B (which is absurd, since B is abstract and therefore it can’t be anybody effective class!).
I found out that the instance was actually a Hibernate proxy, which shouldn’t be a problem if I accessed the class using the Grails domainClass attribute. But still was. Let’s put it in code:
void testThatTheEffectiveClassIsNotAbstract(Long id) { assert B.get(id).getClass() != B_$$_javassist_100 assert B.get(id).domainClass.clazz != B Sql.newInstance(ctx.dataSource).eachRow("select class from a where id = ${id}") { it.class == D.name } }
So, this test was failing in a certain situation for only certain instances. WTF? Anyway, I’m sick of having problems with the whole Hibernate proxy thing and I couldn’t spend time figuring out the whole thing (and moreover, it was impossible for me to reproduce it in a test case), so I ended up adding the the following method to my (constantly growing) GrailsUtils.groovy class (although maybe I should rename it to GrailsHacks.groovy Image may be NSFW.
Clik here to view. ):
import java.lang.reflect.Modifier import static org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsHibernateUtil.unwrapIfProxy static Class getDomainClassInstanceEffectiveClass(instance) { Class proxiedClass = instance.domainClass.clazz Modifier.isAbstract(proxiedClass.getModifiers()) ? unwrapIfProxy(instance).getClass() : proxiedClass }
which actually got the correct class everytime. Surprising? I don’t know what to think anymore…