其实也没什么特别的,就是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