2014-11-03 2 views
0

Мне нужно динамически найти класс экземпляра подтипа java.util.Map, являющегося объявленным полем в сущности JPA, здесь EventDetail экземпляры в details карте:ClassNotFoundException при поиске родового типа объявленного поля java.util.Map объекта JPA (GlassFish 3)

@Entity 
@Table(name = "EVENTS") 
public class Event implements Serializable 
{ 
    ... 

    @OneToMany(mappedBy = "event", fetch = FetchType.LAZY) 
    @MapKey(name = "key") 
    private Map<String, EventDetail> details; 

    ... 

    public Map<String, EventDetail> getDetails() 
    { 
     return (this.details); 
    } 

    ... 
} 

EventDetail нет ничего особенного:

@Entity 
@Table(name = "EVENT_DETAILS") 
public class EventDetail implements Serializable 
{ 
    private static final long serialVersionUID = -1425743343118085745L; 

    @Id 
    @Column(name = "EVENT_DETAIL_ID") 
    private Long    id; 

    @ManyToOne(fetch = FetchType.EAGER, optional = false) 
    @JoinColumn(name = "EVENT_ID", referencedColumnName = "EVENT_ID") 
    private Event    event; 

    ... 
} 

отображения являются правильными, предположим, что. Код процесса в КДИ боба и идет как:

// clazz is the one declaring the map: find generic type (of value)! 
ParameterizedType mapType = (ParameterizedType) clazz.getDeclaredField("details").getGenericType(); 
Type mapValueType = mapType.getActualTypeArguments()[1]; // get EventDetail type 

Class<?> mapValueClass = Class.forName(mapValueType.toString()); // FAIL: CNFE! 
// Class<?> mapValueClass = Class.forName(mapValueType.toString(), true, EventDetail.class.getClassLoader()); 
// Class<?> mapValueClass = Class.forName(mapValueType.toString(), true, clazz.getClassLoader()); 
// Class<?> mapValueClass = Class.forName(mapValueType.toString(), true, Thread.currentThread().getContextClassLoader()); 

Method mapGetMethod = method.getReturnType().getMethod("get", Object.class); 

methods.add(mapGetMethod); 

// set return type to whatever the map defines 
clazz = mapValueClass; 

Я получаю ClassNotFoundException при вызове любой из вариантов Class.forName():

java.lang.ClassNotFoundException: class tld.company.compliance.coiresultmgmt.entity.EventDetail 
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1509) 
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1359) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:270) 
    at tld.company.coi.resultmgmt.view.BaseEventHistoryManager.getHistoryStringValuesFor(BaseEventHistoryManager.java:926) 
. 
. 
. 

Q: Что я делаю неправильно? Как мне получить класс?

Это в GlassFish 3.2.1 env. используя EclipseLink 2.3 в качестве поставщика JPA.

ответ

1

Проблема в том, что Type.toString() выходы "class " до фактического названия класса, например "class tld.company.compliance.coiresultmgmt.entity.EventDetail". Это показано в stacktrace, но его можно легко пропустить.

Вам необходимо удалить эту часть, например. подобные

String typeString = mapValueType.toString(); 

// cut type from type string, otherwise CNFE! 
Class<?> mapValueClass = Class.forName(typeString.substring(typeString.indexOf(' ') + 1)); 
Смежные вопросы