Java JPA:EntityGraph和map

Java JPA:EntityGraph和map,java,jpa,eclipselink,entitygraph,Java,Jpa,Eclipselink,Entitygraph,我使用EclipseLink 2.6.3作为JPA提供者。我有两个实体: @Entity public class ClassA{ @Id private String uuid; private String comment; @OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL,mappedBy = "classA",orphanRemoval = false) @MapKey(

我使用EclipseLink 2.6.3作为JPA提供者。我有两个实体:

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

如何修复它?这是一个bug还是我做错了什么?

免责声明-我不是EclipseLink开发人员,我可能是错的

我发现问题在于,在EntityGraph中,Map不被视为集合。因此,我在org.eclipse.persistence.internal.sessions.AbstractSession中添加了一些代码,作为解决问题的临时解决方法:

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);
   }
公共无效加载(对象objectOrCollection、AttributeGroup组、ClassDescriptor referenceDescriptor、boolean fromFetchGroup){
if(objectOrCollection==null | | group==null){
返回;
}       
if(对象或集合实例集合){
迭代器迭代器=((集合)objectOrCollection.Iterator();
while(iterator.hasNext()){
加载(iterator.next(),group,referenceDescriptor,fromFetchGroup);
}
}//我的代码开始了
else if(对象或集合实例映射){
Map Map=(Map)objectOrCollection;
迭代器it=map.entrySet().Iterator();
while(it.hasNext()){
Map.Entry=it.next();
加载(entry.getValue(),group,referenceDescriptor,fromFetchGroup);
}
}//我的代码结束了
否则{
ClassDescriptor concreteDescriptor=referenceDescriptor;
if(concreteDescriptor.hasInheritation()&&!objectOrCollection.getClass().equals(concreteDescriptor.getJavaClass())){
concreteDescriptor=concreteDescriptor.getInheritancePolicy().getDescriptor(objectOrCollection.getClass());
}
AttributeGroup concreteGroup=group.findGroup(concreteDescriptor);
加载(objectOrCollection,concreteGroup,this,fromFetchGroup);
}

}

JPA合同规定javax.persistence.Query.getResultList()不允许抛出ClassCastException,因此您可以断定这是一个bug,应该向您的JPA提供者报告。在Hibernate 5.0.9.Final中,它似乎工作得很好。@Nicholas据我所知,Hibernate完全忽略了fetch graph。请看我的问题-在我的测试中,我从hibernate中得到了两个完全不同的查询,一个是上面的查询字符串,另一个是上面的整个代码段。实体图似乎比查询字符串优化得多。这里的问题是一样的:自2016年以来已经存在错误,尚未解决->
[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)
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);
   }