2016-06-10 12 views
0

Ich benutze EclipseLink 2.6.3 als JPA-Anbieter. Ich habe zwei Entitäten:JPA: EntityGraph und Karte

@Entity 
public class ClassA{ 

    @Id 
    private String uuid; 

    private String comment; 

    @OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL,mappedBy = "classA",orphanRemoval = false) 
    @MapKey(name="code") 
    private Map<String,ClassB> texts; 
    //+ getters and setters 
} 

@Entity 
public class ClassB { 

    @Id 
    private String uuid; 

    private String code; 

    private String name; 

    @ManyToOne 
    @JoinColumn(name = "comeColname") 
    private ClassA classA; 

    //+getters and setters 
} 

Wenn ich ClassA-Entity ohne EntityGraph laden, funktioniert alles gut. Allerdings, wenn ich den folgenden Code tun:

String queryString="SELECT a FROM ClassA a WHERE a.uuid='dj000000001111111111a1'"; 
EntityGraph<ClassA> eg = em.createEntityGraph(ClassA.class); 
eg.addAttributeNodes(new String[]{"uuid","comment"}); 
eg.addSubgraph("texts").addAttributeNodes(new String[]{"uuid","code","name"}); 
Query query = em.createQuery(queryString); 
query.setHint("javax.persistence.fetchgraph", eg); 
List<ClassA> items=query.getResultList(); 
em.close(); 

Ich erhalte die folgende Ausnahme:

[EL Warning]: 2016-06-10 13:40:20.093--ServerSession(1266534280)--java.lang.ClassCastException: 
    java.util.Hashtable cannot be cast to org.eclipse.persistence.queries.FetchGroupTracker 
    at org.eclipse.persistence.descriptors.FetchGroupManager.getObjectFetchGroup(FetchGroupManager.java:695) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.load(ObjectBuilder.java:778) 
    at org.eclipse.persistence.internal.sessions.AbstractSession.load(AbstractSession.java:5189) 
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1192) 
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:904) 
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1134) 
    at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:460) 
    at org.eclipse.persistence.internal.sessions.AbstractSession.internalExecuteQuery(AbstractSession.java:3271) 
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1857) 
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1839) 
    at org.eclipse.persistence.internal.indirection.NoIndirectionPolicy.valueFromQuery(NoIndirectionPolicy.java:326) 
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.valueFromRowInternal(ForeignReferenceMapping.java:2334) 
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.valueFromRow(ForeignReferenceMapping.java:2178) 
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.readFromRowIntoObject(ForeignReferenceMapping.java:1505) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoObject(ObjectBuilder.java:462) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:1005) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneNormally(ObjectBuilder.java:899) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:852) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:735) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:689) 
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:805) 
    at org.eclipse.persistence.queries.ReadObjectQuery.registerResultInUnitOfWork(ReadObjectQuery.java:895) 
    at org.eclipse.persistence.queries.ReadObjectQuery.executeObjectLevelReadQuery(ReadObjectQuery.java:562) 
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1175) 
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:904) 
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1134) 
    at org.eclipse.persistence.queries.ReadObjectQuery.execute(ReadObjectQuery.java:441) 
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1222) 
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896) 
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1857) 
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1839) 
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804) 
    at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258) 
    at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:465) 

Wie es zu beheben? Ist das ein Fehler oder mache ich etwas falsch?

+0

Der Vertrag JPA sagt, dass _javax.persistence.Query.getResultList() _ nicht zu werfen erlaubt Classcast so können Sie Schluss, dass dies ein Fehler ist und es sollte Ihrem JPA-Provider gemeldet werden –

+0

Scheint in Hibernate 5.0.9.Final gut zu funktionieren. –

+0

@Nicholas soweit ich weiß Hibernate ignoriert Fetch Graph überhaupt. Siehe meine Frage - http://stackoverflow.com/questions/37054082/hibernate-ignores-fetchgraph –

Antwort

1

Haftungsausschluss - Ich bin kein EclipseLink-Entwickler und kann mich irren.

Wie ich herausgefunden habe, ist das Problem, dass Map nicht als Sammlung in EntityGraph betrachtet wird. So habe ich einige Code org.eclipse.persistence.internal.sessions.AbstractSession als Aushilfe Abhilfe für mein Problem:

public void load(Object objectOrCollection, AttributeGroup group, ClassDescriptor referenceDescriptor, boolean fromFetchGroup) { 
    if (objectOrCollection == null || group == null) { 
     return; 
    }  
    if (objectOrCollection instanceof Collection) { 
     Iterator iterator = ((Collection)objectOrCollection).iterator(); 
     while (iterator.hasNext()) { 
      load(iterator.next(), group, referenceDescriptor, fromFetchGroup); 
     } 
    }//MY CODE STARTS 
    else if(objectOrCollection instanceof Map){ 
     Map<Object, Object> map = (Map)objectOrCollection; 
     Iterator<Map.Entry<Object, Object>> it = map.entrySet().iterator(); 
     while (it.hasNext()) { 
      Map.Entry<Object, Object> entry = it.next(); 
      load(entry.getValue(), group, referenceDescriptor, fromFetchGroup); 
     } 
    }//MY CODE ENDS 
    else { 
     ClassDescriptor concreteDescriptor = referenceDescriptor; 
     if (concreteDescriptor.hasInheritance() && !objectOrCollection.getClass().equals(concreteDescriptor.getJavaClass())){ 
      concreteDescriptor = concreteDescriptor.getInheritancePolicy().getDescriptor(objectOrCollection.getClass()); 
     } 
     AttributeGroup concreteGroup = group.findGroup(concreteDescriptor); 
     concreteDescriptor.getObjectBuilder().load(objectOrCollection, concreteGroup, this, fromFetchGroup); 
    } 

}