我在 Eclipselink 中有一个复杂的动态查询,它的 case 表达式涉及两个不同的列,一个是 VARCHAR2,一个是 NVARCHAR2。
它需要是一个 case 表达式,因为我还希望能够按该结果列进行排序,所以我不能同时查询两者。在 Java 中,两者都只是映射为一个字符串,所以你甚至看不出有什么区别。
对于我的查询,Eclipselink 创建了以下选择表达式:
CASE
WHEN (t9.STRINGVALUE IS NOT NULL)
THEN t9.STRINGVALUE
ELSE t10.OTHERSTRINGVALUE
END ,
标准代码为:
Expression<String> str = firstRoot.get("stringValue");
Expression<String> strExp = cb.<String> selectCase().when(cb.isNotNull(str), str)
.otherwise(otherRoot.<String> get("otherStringValue"));
q.multiselect(..., strExp, ...);
这会导致 Oracle 失败并出现 ORA-12704:字符集不匹配。我想修改代码以产生
cast(t10.OTHERSTRINGVALUE as NVARCHAR2(50),
但我不知道怎么做。
我在实体字段上尝试了一个转换器,或者在两个字段的 .get() 表达式上尝试了一个 .as(String.class)。
所以问题是:有没有办法将像 NVARCHAR2 这样的 Oracle 类型传递给 .as() 表达式?我是否可以使用标准 API 插入对 CAST(... as NVARCHAR2) 的调用?有没有其他方法可以让它生成自定义 SQL,因为我真的无法重写整个查询,只是因为 JPA 或 EL 不提供您可能需要一些自定义 SQL 的可能性......