Blog

JPQL CASE WHEN 写法一则

Cover Image for JPQL CASE WHEN 写法一则
ZD
ZD

其实也没什么特别的,就是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)中要用原生字符串比较。

ZD 2012-8-24