Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa eclipselink嵌套批取_Jpa_Eclipselink_Batch Fetching - Fatal编程技术网

Jpa eclipselink嵌套批取

Jpa eclipselink嵌套批取,jpa,eclipselink,batch-fetching,Jpa,Eclipselink,Batch Fetching,我用3个实体建立了一个非常简单的模型: 部门有多个(关系员工) 员工有多个地址(关系地址) 地址 我想从获取部门中批量获取员工和地址,因此我有以下JPL: select d from Department d 我添加了以下提示: query.setHint(QueryHints.BATCH, "d.employees.addresses"); 但我经常会遇到以下错误: Exception [EclipseLink-6089] (Eclipse Persistence Services -

我用3个实体建立了一个非常简单的模型:

  • 部门
    有多个(关系
    员工
  • 员工
    有多个地址(关系
    地址
  • 地址
我想从获取部门中批量获取员工和地址,因此我有以下JPL:

select d from Department d
我添加了以下提示:

query.setHint(QueryHints.BATCH, "d.employees.addresses");
但我经常会遇到以下错误:

Exception [EclipseLink-6089] (Eclipse Persistence Services - 2.4.2.v20130514-5956486): org.eclipse.persistence.exceptions.QueryException
Exception Description: The expression has not been initialized correctly.  Only a single ExpressionBuilder should be used for a query. 
For parallel expressions, the query class must be provided to the ExpressionBuilder constructor, and the query's ExpressionBuilder must 
always be on the left side of the expression. 
Expression: [
Base my.jpa.test.Department]
Query: ReadAllQuery(referenceClass=Department sql="SELECT ID, NAME FROM DEPARTMENT")
    at org.eclipse.persistence.exceptions.QueryException.noExpressionBuilderFound(QueryException.java:904)
    at org.eclipse.persistence.expressions.ExpressionBuilder.getDescriptor(ExpressionBuilder.java:195)
    at org.eclipse.persistence.internal.expressions.DataExpression.getContainingDescriptor(DataExpression.java:214)
    at org.eclipse.persistence.internal.expressions.DataExpression.getMapping(DataExpression.java:221)
    at org.eclipse.persistence.internal.expressions.QueryKeyExpression.getMapping(QueryKeyExpression.java:426)
    at org.eclipse.persistence.mappings.DatabaseMapping.extractNestedExpressions(DatabaseMapping.java:464)
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.prepareNestedBatchQuery(ForeignReferenceMapping.java:882)
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.batchedValueFromRow(ForeignReferenceMapping.java:220)
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.valueFromRow(ForeignReferenceMapping.java:2046)
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.buildCloneFromRow(ForeignReferenceMapping.java:289)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoWorkingCopyClone(ObjectBuilder.java:1617)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneFromRow(ObjectBuilder.java:1769)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:672)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:609)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:564)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:777)
    at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:797)
    at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:434)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1150)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:852)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1109)
    at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:393)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1197)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2879)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1607)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1589)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1554)
    at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:231)
    at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:411)
    at my.jpa.test.Department.main(Department.java:124)
如果我在
@OneToMany
关系上直接使用
@BatchFetch
注释,那么查询工作得很好

我如何在不使用注释的情况下解决此问题(因为注释将强制对我的所有查询执行批处理查询)


如果您需要其他信息或完整的代码,我很乐意提供。

我最近也遇到了同样的问题,不幸的是我也无法解决。作为一种解决方法,我在父实体中使用@NamedQuery注释定义了SELECT:

@Entity
@NamedQueries
(
    { 
        @NamedQuery(name = "Department.batchFetch", query = "Select d from Department d", 
        hints = 
        {
            (...)
            // works with JOIN/EXISTS too
            @QueryHint(name = QueryHints.BATCH_TYPE, value = "IN"),
            @QueryHint(name = QueryHints.BATCH, value = "d.employees.addresses")

        }), 
    }
)
public class Person 
{
    (...)
}
调用NamedQuery的方法将具有:

Query query = em.createNamedQuery(queryName); // "Department.batchFetch"
List<Department> result = query.getResultList();
Query Query=em.createNamedQuery(queryName);//“部门批取”
List result=query.getResultList();

这并不完全是我想要的(我不能自定义我想在运行时加载的实体),但它比让所有查询使用@BatchQuery for me的批取要好。

我通过使用自定义程序并创建一个扩展OneToOneMapping的类来解决问题(但我认为它也适用于许多OneToOneMapping),通过重写prepareNestedBatchQuery方法

替换:

            if (expressionBuilder.getQueryClass() == null) {
                expressionBuilder.setSession(query.getSession().getRootSession(null));
                expressionBuilder.setQueryClass(query.getReferenceClass());
            }
与:


您的DescriptorCustomizer必须使用新的映射向量调用descriptor.setMappings。

这已在EclipseLink 2.6.0中得到解决。我不知道为什么使用NamedQuery可以工作,但它可以工作。自EclipseLink 2.6.0以来,该问题已得到解决。
            if (expressionBuilder.getQueryClass() == null) {
                expressionBuilder.setSession(query.getSession().getRootSession(null));
                expressionBuilder.setQueryClass(query.getReferenceClass());
            } else if (expressionBuilder.getSession() == null) {
                expressionBuilder.setSession(query.getSession().getRootSession(null));
            }