EclipseLink JPA:我可以从一个构建器运行多个查询吗? [英] EclipseLink JPA: Can I run multiple queries from one builder?

查看:88
本文介绍了EclipseLink JPA:我可以从一个构建器运行多个查询吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法可以构建和运行Criteria查询。该查询执行我想要的操作,特别是它根据用户输入过滤(和排序)记录。



此外,查询大小仅限于屏幕上的记录数。这很重要,因为数据表可能非常大。



但是,如果应用了过滤器,我想计算查询返回的记录数没有限制。因此,这意味着运行两个查询:一个查询获取记录,然后一个查询对整个集合中的记录进行计数。看起来像这样:

  public List< Log> runQuery(TableQueryParameters tqp){

//获取构建器,查询和根

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery< Log>查询= builder.createQuery(Log.class);
Root< Log>根= query.from(Log.class);

//构建请求的过滤器

谓词filter = null;
for(TableQueryParameters.FilterTerm ft:tqp.getFilterTerms()){

//此部分通过用户输入运行,并构造
//谓词

}
if(filter!= null)query.where(filter);

//附加请求的订购

List< Order> orders = new ArrayList< Order>();
for(TableQueryParameters.SortTerm st:tqp.getActiveSortTerms()){

// //此部分构造了Order对象

}
if(! orders.isEmpty())query.orderBy(订单);

//运行查询

TypedQuery< Log> typedQuery = em.createQuery(query);
typedQuery.setFirstResult((int)tqp.getStartRecord());
typedQuery.setMaxResults(tqp.getPageSize());
List< Log> list = typedQuery.getResultList();

//如果需要结果大小,请立即获取它

if(tqp.isNeedResultSize()){
CriteriaQuery< Long> countQuery = builder.createQuery(Long.class);
countQuery.select(builder.count(countQuery.from(Log.class)));
if(filter!= null)countQuery.where(filter);
tqp.setResultSize(em.createQuery(countQuery).getSingleResult()。intValue());
}

退货清单;
}

结果是,我在同一个CriteriaBuilder上调用了createQuery两次,并且共享两者之间的谓词对象(过滤器)。当我运行第二个查询时,我有时 收到以下消息:


Exception [EclipseLink-6089]( Eclipse Persistence Services-
2.2.0.v20110202-r8913):
org.eclipse.persistence.exceptions.QueryException异常
描述:该表达式尚未正确初始化。单个ExpressionBuilder仅
可以用于查询。对于并行的
表达式,必须将查询类提供给ExpressionBuilder
构造函数,而查询的ExpressionBuilder必须始终位于表达式的
左侧。表达式:[Base
com.myqwip.database.Log]查询:ReportQuery(referenceClass = Log)位于
org.eclipse.persistence.exceptions.QueryException.noExpressionBuilderFound(QueryException.java:874)

org.eclipse.persistence.expressions.ExpressionBuilder.getDescriptor(ExpressionBuilder.java:195)

org.eclipse.persistence.internal.expressions.DataExpression.getMapping(DataExpression.java :214)


有人可以告诉我为什么此错误间歇出现,我应该怎么做?

解决方案

对问题的简短回答:是的,可以,但只能按顺序进行。



在上面的方法中,您开始创建第一个查询,然后开始创建第二个查询,执行第二个查询,然后执行第一个查询。



我遇到了完全相同的问题。我不知道为什么它会时断时续。



换句话说,您开始创建第一个查询,然后在完成之前开始创建并执行另一个查询。 / p>

Hibernate不抱怨,但是eclipselink不喜欢它。



如果只是从查询计数开始,执行它,然后创建并执行另一个查询(通过将其拆分为2种方法来完成),eclipselink不会抱怨。



请参见 https: //issues.jboss.org/browse/SEAMSECURITY-91


I have a method that builds and runs a Criteria query. The query does what I want it to, specifically it filters (and sorts) records based on user input.

Also, the query size is restricted to the number of records on the screen. This is important because the data table can be potentially very large.

However, if filters are applied, I want to count the number of records that would be returned if the query was not limited. So this means running two queries: one to fetch the records and then one to count the records that are in the overall set. It looks like this:

public List<Log> runQuery(TableQueryParameters tqp) {

    // get the builder, query, and root

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Log> query = builder.createQuery(Log.class);
    Root<Log> root = query.from(Log.class); 

    // build the requested filters

    Predicate filter = null;
    for (TableQueryParameters.FilterTerm ft : tqp.getFilterTerms()) {

       // this section runs trough the user input and constructs the 
       // predicate

    }
    if (filter != null) query.where(filter);

    // attach the requested ordering

    List<Order> orders = new ArrayList<Order>();
    for (TableQueryParameters.SortTerm st : tqp.getActiveSortTerms()) {

        // this section constructs the Order objects

    }
    if (!orders.isEmpty()) query.orderBy(orders);        

    // run the query

    TypedQuery<Log> typedQuery = em.createQuery(query);
    typedQuery.setFirstResult((int) tqp.getStartRecord());
    typedQuery.setMaxResults(tqp.getPageSize());
    List<Log> list = typedQuery.getResultList();

    // if we need the result size, fetch it now

    if (tqp.isNeedResultSize()) {
        CriteriaQuery<Long> countQuery = builder.createQuery(Long.class);
        countQuery.select(builder.count(countQuery.from(Log.class)));
        if (filter != null) countQuery.where(filter);
        tqp.setResultSize(em.createQuery(countQuery).getSingleResult().intValue());
    }

    return list;
}

As a result, I call createQuery twice on the same CriteriaBuilder and I share the Predicate object (filter) between both of them. When I run the second query, I sometimes get the following message:

Exception [EclipseLink-6089] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): 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 com.myqwip.database.Log] Query: ReportQuery(referenceClass=Log ) at org.eclipse.persistence.exceptions.QueryException.noExpressionBuilderFound(QueryException.java:874) at org.eclipse.persistence.expressions.ExpressionBuilder.getDescriptor(ExpressionBuilder.java:195) at org.eclipse.persistence.internal.expressions.DataExpression.getMapping(DataExpression.java:214)

Can someone tell me why this error shows up intermittently, and what I should do to fix this?

解决方案

Short answer to the question : Yes you can, but only sequentially.

In the method above, you start creating the first query, then start creating the second, the execute the second, then execute the first.

I had the exact same problem. I don't know why it's intermittent tough.

I other words, you start creating your first query, and before having finished it, you start creating and executing another.

Hibernate doesn't complain but eclipselink doesn't like it.

If you just start by the query count, execute it, and then create and execute the other query (what you've done by splitting it in 2 methods), eclipselink won't complain.

see https://issues.jboss.org/browse/SEAMSECURITY-91

这篇关于EclipseLink JPA:我可以从一个构建器运行多个查询吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆