2009-07-16 9 views
5

Ich habe einen JSF-Konverter, den ich für eine SelectItem-Liste verwenden, die mehrere verschiedene Entitätstypen enthält. In der getAsString() Methode erstelle ich die Zeichenfolge als Klassenname mit dem Suffix ":" und der ID.Loading javassist-ed Hibernate-Entität

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

Dies ermöglicht es mir, die richtige Einheit in den getAsObject() auf dem Rückweg von der Benutzeroberfläche zu laden, indem Sie diese:

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); 

Mein Problem ist, dass meine Einheit in getAsString() ein Proxy ist. Anstatt also com.company.MyEntity zu bekommen, wenn ich getClass() mache. GetName() bekomme ich com.company.MyEntity_$$_javassist_48, dann scheitert es an der find().

Gibt es einen Weg (neben der Manipulation von Zeichenketten), den konkreten Klassennamen zu erhalten (zB com.company.MyEntity)?

Danke.

Antwort

9

Statt superClass.getClass() versuchen Sie org.hibernate.proxy.HibernateProxyHelper.getClassWithoutInitializingProxy(superClass).

+0

I‘ ve verwendet ((HibernateProxy) -Entity) .getHibernateLazyInitializer(). getEntityName() oder getPersistentClass() aber HibernateProxy Wraps, so ist es wahrscheinlich der Weg zu gehen. –

+11

oder einfach Hibernate.getClass() –

+0

Große Antwort Jungs. Es hat mir sehr geholfen. – Mythul

6

Es gibt einen wichtigen Unterschied zwischen Hibernate.getClass() und HibernateProxyHelper! Die HibernateProxyHelper gibt immer die übergeordnete Klasse, die die Tabelle in der Datenbank darstellt, wenn Sie und Einheit, die

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

und

@DiscriminatorValue(value = EntityClass.TABLE_DISCRIMINATOR) 

in der Unterklasse zugeordnet wird, verwendet wird.

Hibernate.getClass (...) gibt die echte Unterklasse für diese zurück.

3

Wenn mit abstrakter Entität Erbe kombiniert (AbstractEntity <-ConcreteEntity < - ConcreteEntityProxy), die Persistenz-Klasse bekommt einfach nicht genug:

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

stattdessen die Implementierungsklasse erhalten:

protected <T> T deproxy(T maybeProxy) { 
    if (maybeProxy instanceof HibernateProxy) { 
     return (T) ((HibernateProxy) maybeProxy).getHibernateLazyInitializer().getImplementation(); 
    } 
    return maybeProxy; 
}