我在hibernate中写了下面的查询,它给了我NullPointerException
SELECT new com.reddy.ReddyDTO( col1, IF(STRCMP(COL8, 'zero')=0, 'string', col2) )
FROM entity
然而,由于无法将第二列的数据类型确定为字符串类型,因此它正在抛弃NPE。
我可以看到它无法通过查看下面的位置来确定类型
在org.hibernate.hql.ast.tree.ConstructorNode.resolveConstructor(String path)
方法中,字段constructorArgumentTypes
的值为(org.hibernate.type.StringType, null)
如何让hibernate理解这个列是String数据类型? (我已经尝试将“字符串”放在双引号中,但这给了我错误)
答案 0 :(得分:2)
嗯......这个IF
表达是什么?我在参考文档中找不到它。据我所知,最接近的是case
表达式:
“简单”案例,案例......当......然后......结束,“搜查”案件,案件......然后......其他......结束
但我怀疑你可以在构造函数表达式中使用它。
更新:看来Hibernate比我想象的要好,你可以在构造函数表达式中使用一个案例:
SELECT new com.reddy.ReddyDTO(col1, case col8 when 'zero' then 'string' else col2 end) FROM entity
答案 1 :(得分:0)
如果你需要在你的select语句中使用hibernate不知道的数据库函数,你必须在org.hibernate.dialect.Dialect
中定义它,以便hibernate确定正确的返回类型。
你所要做的就是覆盖你的方言,比如说MySQL5InnoDBDialect
,并创建一个像这样的构造函数:
public MySQL5InnoDBDialectExt() {
super();
registerFunction("if_str", new StandardSQLFunction("if", StandardBasicTypes.STRING));
registerFunction("if_int", new StandardSQLFunction("if", StandardBasicTypes.INTEGER));
registerFunction("if_float", new StandardSQLFunction("if", StandardBasicTypes.DOUBLE));
registerFunction("strcmp", new StandardSQLFunction("strcmp", StandardBasicTypes.INTEGER));
}
不幸的是,你必须为不同的返回类型定义几个函数(如果你需要它),因为hibernate只能动态地确定返回类型,如果它对应于第一个参数的类型,则不是这种情况这里。
在hibernate.dialect
中设置hibernate.cfg.xml
属性后,您的查询现在可以正常使用(请注意使用IF_STR
代替IF
):
SELECT new com.reddy.ReddyDTO( col1, IF_STR(STRCMP(COL8, 'zero')=0, 'string', col2) )
FROM entity