JPQL CASE WHEN 写法一则

其实也没什么特别的,就是JPA2中,JPQL的解析还是有硬伤啊,害得我摸索了好一阵子。

请看:

public static final String HQL_FIND_TRANSACTION_AMOUNT = "select new foo.bar.service.report.tax.TransactionAmountField(at.account, sum( CASE at.transactionSign WHEN 'CREDIT' THEN at.amount * 1 WHEN 'DEBIT' THEN at.amount * -1 ELSE at.amount END))" + " from AccountTransaction at" + " where at.account.id > 0 and at.transactionType in :tt" + " and at.settled=true and (at.settlementDate BETWEEN :beginDate AND :endDate)" + " group by at.account";

这里的JPQL是根据 tansaction type 统计该type有多少金额,本来简单的,但是金额加上符号后,就不简单了,要分正负了。sum函数因此变复杂了。用到了CASE WHEN。CASE WHEN本来也没什么,照着语法写呗。由于我判断的不是一般的数据,没错,

at.transactionSign 是一个enum,鉴于WHERE部分的写法 ”where at.account.id > 0 and at.transactionType in :tt” ,我HLL的写上了 foo.bar.at.TransactionSign.CREDIT 这样的全包名,运行结果呢,你猜? 错了!

明明现在的JQPL,enum是要用对象的啊,于是开始了漫漫的各种折腾,最后,绝望了,心灰意冷的直接写上了 ‘CREDIT’ 这样的字符串,再试,GC来了,居然成了!

总结下来,就是在where中可以使用对象和enum比较,而在其他部分(如select)中要用原生字符串比较。

Bill 2012-8-24

© 2021, XZD