我正在使用条件API来创建我的查询。由于特殊的排序算法,我使用了一个“按大小写排序”表达式。我的单元测试在内存中使用了H2 DB,并且正在工作。在开发阶段,我们使用Oracle DB,并且在那里我得到了一个“SQLException:“ORA-12704”。
假设我的根实体'Foo'有一个'Bar'的集合。Bar有一个属性'myOrderByColumn'
public class Bar {
...
@NotBlank
@javax.validation.constraints.Size(max = 255)
@Column(name = "MYORDERBYCOL")
private java.lang.String myOrderByColumn;
...
}
下面是产生异常的代码,它创建稍后在CriteriaQuery中使用的Order对象。orderBy(..)
private Order buildOrderBy(final CriteriaBuilder cb,
final Root<Foo> rootEntity,
final List<String> somehowSpecialOrderedList) {
final Expression<String> orderByColumn =
rootEntity.join(Foo_.bars, JoinType.LEFT).get(Bars.myOrderByColumn);
CriteriaBuilder.SimpleCase<String, Integer> caseRoot = cb.selectCase(orderByColumn);
IntStream.range(0, somehowSpecialOrderedList.size())
.forEach(i -> caseRoot.when(somehowSpecialOrderedList.get(i), i));
final Expression<Integer> selectCase = caseRoot.otherwise(Integer.MAX_VALUE);
return cb.asc(selectCase);
}
我查看了Oracle数据库,列“myOrderByColumn”的类型是NVARCHAR 2(255)。
我猜这里的问题是SQL查询中的“when”部分必须与数据库列“MYORDERBYCOL”的类型匹配,即NVARCHAR 2。在Java中我使用字符串。可能Hibernate没有正确地转换此类型!?
我可以通过以下方式生成数据库ORA-12704错误
SELECT FOO.id
FROM FOO
LEFT OUTER JOIN BAR ON FOO.id = BAR.fk_id
ORDER BY
CASE FOO.myorderbycol
WHEN '20' THEN 1
ELSE 2
END ASC;
此SQL有效
SELECT FOO.id
FROM FOO
LEFT OUTER JOIN BAR ON FOO.id = BAR.fk_id
ORDER BY
CASE FOO.myorderbycol
WHEN cast('20' as NVARCHAR2(255))
THEN 1ELSE 2
END ASC;
我必须如何使用标准API调整我的按情况排序表达式,以便查询适用于任何数据库?(以后必须至少适用于H2、Oracle、MS SQL、PostgreSQL)
1条答案
按热度按时间pkwftd7m1#
在我看来是Oracle的问题。您使用的是哪个版本?您可以尝试其他可能有效的方法。