Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading javassist-ed Hibernate entity

I have a JSF converter that I use for a SelectItem list containing several different entity types. In the getAsString() method I create the string as the class name suffixed with ":" and the ID.

MySuperClass superClass = (MySuperClass)value;
if(superClass != null) {
  return String.valueOf(superClass.getClass().getName()+":"+superClass.getId());
}

This allows me to load the correct entity in the getAsObject() on the way back from the UI by doing this :

String className = value.substring(0, value.indexOf(":"));
long id = Long.parseLong(value.substring(value.indexOf(":")+1));
Class<T> entitySuperClass = (Class<T>) Class.forName(className);
MySuperClass superClass = (MySuperClass)getEntityManager().find(entitySuperClass, id);

My problem is that my entity in getAsString() is a proxy. So instead of getting com.company.MyEntity when I do a getClass().getName() I am getting com.company.MyEntity_$$_javassist_48 so then it fails on the find().

Is there any way (aside from String manipulation) to get the concrete class name (eg. com.company.MyEntity)?

Thanks.

like image 286
Damo Avatar asked Jul 16 '09 18:07

Damo


3 Answers

Instead of superClass.getClass() try org.hibernate.proxy.HibernateProxyHelper.getClassWithoutInitializingProxy(superClass).

like image 153
ChssPly76 Avatar answered Oct 13 '22 19:10

ChssPly76


There is one important difference between Hibernate.getClass() and HibernateProxyHelper! The HibernateProxyHelper always returns the superclass that represents the table in the database if you have and entity that is mapped using

@Table(name = SuperClass.TABLE_NAME)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = SuperClass.TABLE_DISCRIMINATOR, discriminatorType = DiscriminatorType.STRING)

and

@DiscriminatorValue(value = EntityClass.TABLE_DISCRIMINATOR)

in the subclass.

Hibernate.getClass(...) returns the real subclass for those.

like image 32
Daniel Bleisteiner Avatar answered Oct 13 '22 19:10

Daniel Bleisteiner


When combined with abstract entity's inheritance (AbstractEntity <- ConcreteEntity <- ConcreteEntityProxy), getting the persistence class is just not enough:

// This should fail - trying to create an abstract class
HibernateProxyHelper.getClassWithoutInitializingProxy(superClass).newInstance()

instead get the implementation class:

protected <T> T deproxy(T maybeProxy) {
    if (maybeProxy instanceof HibernateProxy) {
        return (T) ((HibernateProxy) maybeProxy).getHibernateLazyInitializer().getImplementation();
    }
    return maybeProxy;
}
like image 28
Asaf Avatar answered Oct 13 '22 18:10

Asaf