java - QueryDSL 按计算字段排序
问题描述
在我们的应用程序中,我们使用 querydsl 来获取实体并将它们转换为表示对象。此演示对象具有名为 的字段active
。这取决于实体的某个日期是在今天之前(活动 = 假)还是今天之后(活动 = 真)。一切顺利。问题在于尝试按该表达式 ( QEntity.someDate > today
) 进行排序时。这使得hibernate抛出这个错误:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: > near line 3, column 40 [select object.someField as someAlias, (object.someDate > ?1) as active, object as objectAlias
from com.example.Object object
order by object.someDate > ?1 asc]
我创建OrderSpecifier
如下:
@Override
public OrderSpecifier<?> getOrderByClause(SortKey sortKey) {
BooleanExpression expression = getBooleanPath(); // This is the expression: (object.someDate > ?1)
if (sortKey.getSortOrder() == ESortOrder.ASCENDING) {
return new OrderSpecifier(Order.ASC, expression);
}
return new OrderSpecifier(Order.DESC, expression);
}
我也试过这样:
@Override
public OrderSpecifier<?> getOrderByClause(SortKey sortKey) {
BooleanExpression expression = getBooleanPath();
if (sortKey.getSortOrder() == ESortOrder.ASCENDING) {
return new CaseBuilder().when(expression.isFalse()).then(1).otherwise(2).asc();
}
return new CaseBuilder().when(expression.isTrue()).then(1).otherwise(2).desc();
}
这会导致类似的错误:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: > near line 3, column 40 [select object.someField as someAlias, (object.someDate > ?1) as active, object as objectAlias
from com.example.Object object
order by case when (object.someDate > ?1 = ?2) then ?3 else 2 end asc]
最后像这样:
@Override
public OrderSpecifier<?> getOrderByClause(SortKey sortKey) {
BooleanExpression expression = getBooleanPath();
if (sortKey.getSortOrder() == ESortOrder.ASCENDING) {
return new CaseBuilder().when(expression.eq(true)).then(1).otherwise(2).asc();
}
return new CaseBuilder().when(expression.eq(true)).then(1).otherwise(2).desc();
}
这会引发与前一个相同的错误
解决方案
通过创建这样的 order 子句来修复它:
@Override
public OrderSpecifier<?> getOrderByClause(SortKey sortKey) {
BooleanPath path = getBooleanPath();
if (sortKey.getSortOrder() == ESortOrder.ASCENDING) {
return path.asc();
}
return path.desc();
}
private BooleanPath getBooleanPath() {
return Expressions.booleanPath(getFieldName());
}
在我们的例子中,字段名称是字符串的别名"active"
。
推荐阅读
- python - “NoneType”对象不可迭代 - 数据导入
- javascript - 'chromedriver' 可执行文件需要在 PATH 中,但它已经存在
- pytorch - 火炬。优化模型的输入:尝试第二次向后遍历图形,但缓冲区已被释放
- apache-kafka - Kafka compare consecutive values for a key
- node.js - How to shift a particular document from one collection to another using mongoose?
- java - 为什么将null分配给节点不会删除链表中的该节点
- css - How to use parent div font color instead of child
- javascript - how to quick up the process of displaying images in React coming from backend (Django Rest)
- python - Difference in run time complexity of two seemingly similar solutions
- javascript - node.js中的through2和native Transform流有什么区别?