2016-06-10 6 views
0

JPA 공급자로 EclipseLink 2.6.3을 사용합니다. 두 엔티티가 있습니다 :JPA : EntityGraph 및 map

@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 
} 

EntityGraph없이로드 할 때 모든 것이 잘 작동합니다. 나는 다음과 같은 코드 그러나이 경우 :

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

어떻게 그것을 해결하기 위해 :

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

을 나는 다음과 같은 예외를 얻을? 이 버그입니까, 아니면 뭔가 잘못 됐나요?

+0

JPA에 계약 _javax.persistence.Query.getResultList가() _ 당신이 할 수 있도록 ClassCastException를 슬로우 할 수 없습니다 말한다 : 그래서 난 내 문제에 대한 임시 해결 방법으로 org.eclipse.persistence.internal.sessions.AbstractSession에 일부 코드를 추가 이것이 버그이며 JPA 공급자에게보고되어야한다고 결론을 내림 –

+0

최대 절전 모드 5.0.9에서 최종 작동합니다. 최종. –

+0

@Nicholas 나는 Hibernate가 그래프 가져 오기를 전혀 무시한다는 것을 알고있다. 내 질문보기 - http://stackoverflow.com/questions/37054082/hibernate-ignores-fetchgraph –

답변

1

면책 조항 - EclipseLink 개발자가 아니므로 잘못되었습니다.

지도가 EntityGraph에서 컬렉션으로 간주되지 않는다는 것이 발견되었습니다.

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

}