当前位置: 首页 > 知识库问答 >
问题:

JPA标准API顺序按NULL last

狄安歌
2023-03-14

我使用JPA criteria API从数据库中获取记录。我有一个实体记录,其字段dateTime可以为空。我会编码:

public List<Record> find(RecordFilter recordFilter, int page, int pageSize) {
    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Record> criteriaQuery = criteriaBuilder.createQuery(Record.class);
    Root<Record> recordRoot = criteriaQuery.from(Record.class);

    /*
     * JOINS. Left Joins are used for optional fields, or fields inside of the optional fields.
     */
    Join<Record, Agency> recordAgencyJoin = recordRoot.join(RecordTable.FIELD_AGENCY);
    //Some other joins

    //This is where I had the problem. 
    applyOrderBy(criteriaQuery, criteriaBuilder, recordRoot);

    /*
     * Specify which columns to select and their order.
     * criteriaQuery.multiselect(....);
     */              
    applyMultiSelect(recordRoot, recordAgencyJoin, /*other joins*/ criteriaQuery);

    /*
     * criteriaQuery.where(somePredicate);
     */
    applyFilter(recordFilter, criteriaQuery, criteriaBuilder,
            recordRoot, recordAgencyJoin /*, other joins*/);
    TypedQuery<Record> query = entityManager.<Record>createQuery(criteriaQuery);
    RepositoryUtils.applyPagination(query, page, pageSize);
    return query.getResultList();
}


private void applyOrderBy(CriteriaBuilder criteriaBuilder, Root<Record> recordRoot, CriteriaQuery<Record> criteriaQuery) {
    //Other fields to be added to the final sort.

    Order dateTimeDescOrder = criteriaBuilder.desc(recordRoot.get(RecordTable.FIELD_DATE_TIME));
    criteriaQuery.orderBy(dateTimeDescOrder /*, other orders by*/);
}

事实证明,dateTimeField为空的记录首先显示。我使用Postrgres数据库。我会回答这个问题,因为我找到了解决办法。这里有一个类似的帖子。JPA标准查询API和订单(按空)

共有3个答案

邹誉
2023-03-14

JPA或Eclipselink中没有任何内容可以在CriteriaBuilder中使用。

例子:

Order order1 = cBuilder.desc(cBuilder.selectCase().when(cBuilder.isNotNull(from.get('ColumnName1')), from.get('ColumnName1')).otherwise(from.get('ColumnName1')));
CQuery.orderBy(order1);

它会给你最好的答案

吴胜
2023-03-14

JPA规范中没有任何内容可以控制如何处理空值(所有RDBMS都首选默认值)。这在JPQL(基于字符串的查询)或Criteria API中都不可用。有了JPQL,所有主要的JPA提供商都允许使用

NULLS [FIRST|LAST]

在订购子句中。对于标准,您受到标准应用编程接口的约束,所以什么都不可能。我知道数据核心JPA提供了JPA标准应用编程接口的自定义版本,允许规范

Order order = criteriaBuilder.asc(myExpression).nullsFirst();

但很明显,这是特定于JPA提供商的。

洪知
2023-03-14

在这里,我给出了这个任务的答案。

首先,Postgres默认首先返回空值。

SELECT * FROM record ORDER BY date_time_field DESC;

https://stackoverflow.com/a/7621232/4587961

SELECT * FROM record ORDER BY date_time_field DESC NULLS LAST;

其次,我必须改变applyOrderBy方法

private void applyOrderBy(CriteriaBuilder criteriaBuilder, Root<Record> recordRoot, CriteriaQuery<Record> criteriaQuery) {
    //In the class code
    //private static final Date MIN_DATE = new Date(0L);
    final Date MIN_DATE = new Date(0L);

    //We treat records will NULL dateTimeField as if it was MIN_DATE.
    Order dateTimeDescOrder = criteriaBuilder.desc(
            //NULL values - last - WORKAROUND.
            criteriaBuilder.coalesce(recordRoot.get(RecordTable.FIELD_DATE_TIME), MIN_DATE));
    criteriaQuery.orderBy(dateTimeDescOrder);
}

请注意,CriteriaBuilder来自hibernate-jpa-2.1。

/**
 * Create an expression that returns null if all its arguments
 * evaluate to null, and the value of the first non-null argument
 * otherwise.
 *
 * @param x expression
 * @param y value
 *
 * @return coalesce expression
 */
<Y> Expression<Y> coalesce(Expression<? extends Y> x, Y y);
 类似资料:
  • 我有2个班: 我试图创建一个带有动态order by和参数的查询,例如:我想在DrcommentsPK时选择所有Drcomments记录。commentPrimaryCode等于1,其顺序为DrcommentsPK。注释第二代码。这就是我尝试的: 问题是我得到的结果列表没有按commentSecondaryCode desc顺序排序。。 我做错什么了吗?如何做到这一点?如何创建按eMedTable

  • 我被一个简单的问题困住了;如何在ed实体上调用。基本上,我正试图通过JPA标准实现以下目标: 我有以下几点: 如何通过d.name,c.name使用来实现

  • 我的问题是空值必须是最后一个order by语句。下面是我的代码截图。我使用javax持久性标准生成器。我的问题很复杂。 如何通过criteria builder以零价格完成订单?

  • 主要内容:创建条件查询的步骤,标准API查询子句的方法标准(Criteria)API是构建实体及其持久状态查询的最常用方法之一。 它只是定义JPA查询的另一种方法。 Criteria API定义了一个独立于平台的条件查询,用Java编程语言编写。 它是在JPA 2.0中引入的。 这背后的主要目的是提供一种类型安全的方式来表达查询。 创建条件查询的步骤 要创建标准查询,请按照以下步骤操作: - 第1步: 通过在接口实例上调用方法创建接口的对象。 第2步

  • 我正在尝试实现以下内容: 问:我如何用JPA 2标准实现这个? 我可以单独获得asCount结果,但不知道如何将其加入公司 提前感谢。 PS 1。有一个类似的线程使用HiberNate应用编程接口询问子级计数:HiberNate子级计数标准 2。另一个描述该主题的有用线程: JPA CriteriaBuilder——按一对多关系中关联实体的数量排序