在hibernate里用Projection里的一个问题及其解决

本文介绍了一次使用Hibernate进行SQL求和操作时遇到的问题及其解决过程。问题表现为求和结果不正确,通过查看Hibernate生成的SQL语句,发现是由于group by属性未正确命名导致。最终通过修改代码实现正确求和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     在<想看Hibernate生成的SQL语句?>里,我列出怎么来看Hibernate生成sql的方法, 在末尾留了一个小尾巴,今天把它补上.

    程序中的实际场景是这样的, 一个Model类里有contractBw,nodeType,subCompany,overBw等属性, 现在要对contractBw和overBw有三次汇总求和并显示记录条数,分别是按contractBw,nodeType,subCompany来 group by.

    这样在程序中用Projections来做, 有了以下的代码:
              projList.add(Projections.rowCount(),"rowCount");

    projList.add(Projections.sum("contractBw"),"contractBw");
    projList.add(Projections.sum("overBw"),"overBw");
    projList.add(Projections.groupProperty(groupItem),groupItem);

    queryCirteria.setProjection(projList);
    queryCirteria.setResultTransformer(new AliasToEntityMapResultTransformer());

    这里的参数groupItem上层代码可以设定为"contractBw","nodeType", "subCompany",从而达到三次求和可以共用这上面的代码.

    这样写,猛一看没什么问题, 也能跑的通.

    但看页面上的数据时发现问题了,  数据不对劲:  如果一个contractBw为2000M的记录有2条,sum出来和应该是4000M才对,可显示是2000M, 这是怎么回事?

    是什么地方出问题了? 从哪下手? 这样的问题在网上也没法, 只能自己硬着头皮解决了. 幸好自己的IDE里配置了debug功能,于是就跟踪源码了, 胡乱地设置了几个断点后,没发现有什么价值的信息,不过看IDE里方法的调用栈,发现有这么一个preprocessSQL, 难道是与生成的SQL有关? 嘿嘿... 要是真是那样就好了, 可以用hibernate生成的代码在数据库里运行下,看看结果怎样.

     于是在preprocessSQL方法sql = applyLocks( sql, parameters.getLockModes(), dialect );一句处设置了断点. 一运行,还真能看到生成的SQL, 拷到数据库里一执行, 乖乖, 没问题.....

    电光火石间, 我意识到了:
        projList.add(Projections.groupProperty(groupItem),groupItem);
这里出问题了.这里得另起名字,于是改成了
        projList.add(Projections.groupProperty(groupItem),groupItem+"item");

    现在想想,那种感觉太奇妙了!从看到hibernate生成的sql在数据库里执行结果显示出来到意识到问题的根源,感觉这期间不超过一秒钟!
    这样改了后,再启动,没问题了:2000M的记录有2条,sum出来和也是4000M!

    现在回过来头来看看, 是什么促使自己能在这么短的时间能发现并改正程序中的问题呢?在IDE中设置断点用hibernate生成的sql在数据库中执行起到了关键性的作用. 下一篇中将分析结合hibernate的执行过程分析下为什么这样改是正确的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值