您的位置:首页 > 编程语言 > Java开发

spring-data-jpa使用联合主键后出现operand should contain 1 column(s)

2016-10-03 13:55 471 查看
最近做项目遇到个比较坑的地方,今天有空记录下来,希望可以为遇到同样情况的朋友提供一个方法。

  因为业务逻辑上的问题,项目写到前几天突然发现要重新设计数据库某个表的主键。(在团队同学的建议下),采用了之前一直没机会接触过的联合主键。

  项目用的是mySql,数据表修改成联合主键倒没什么问题。(- -! 其实中间还是有个小插曲,因为在SAE上用了myPhpAdmin,将数据表修改成联合主键不像workBench一样操作简便,用sql语句才将表修改成联合主键)。

  接下来改代码就遇到不顺了,首先由于数据表发现了变化,相应的orm就要变,于是从网上学习了hibernate如何实现联合主键的资料后开始着手改代码(这里啰嗦一句,其实联合主键就是多写一个类,联合的属性作为这个类的两个成员,再实现相应的serializable接口和hascode、equals函数就行)。

  entity改完,相应的进行dao层的修改。因为一直用的是spring-data-jpa,继承的是repository接口,再用@Query注解自定义了hql语句,因此也就相应的修改了query注释,改完之后的代码是

    @Query("select u from User u where u.primary.idkey = ?1 and (u.state = '完成签到' or u.state='补签完成')")

    public Page<User> findAllByIdkeyToPage(String idkey,Pageable pageable);

  

  修改完将代码部署到服务器上运行时,执行到相关代码时崩溃了,日志报错"operand should contain 1 column(s)"。

  于是我怀疑是这条hql出了错,于是将hql修改为sql后拿去mySql执行了一次,结果却没问题,顺利拿到了我想要的数据。

  当时就一脸懵逼了,这不可能啊,按理sql可以执行成功的话,hql就是没问题的。无从下手的我只好硬着头皮再去看日志(我一行行找就不信找不到错误的原因)。

  看了很久终于发现了问题的所在(此时大神可能早已在笑话我了)。没错,问题就出在了spring提供的page类。

  本身用page类的原因肯定是为了分页,分页的话追踪到底层是要用到统计语句count的,因此日志中出现了这条语句

  select count(u.openid, u_idkey)  from User u where u.primary.idkey = ?1 and (u.state = '完成签到' or u.state='补签完成') by u.name dedc limit?

  开始怀疑这就是错误的原因。

  于是将换成sql放到mySql一执行,果然报错。再修改,将count(u.openid, u_idkey)改成count( (concat (u.openid, u_idkey) ) ),再执行,果然通过。

  到此,错误的根本原因已确定,使用联合主键时,再用到spring提供的page来执行查询语句就会出错。

  解决方法:抛弃spring-data-jpa提供的page分页,用hibernate的session.createQeury,配合分页参数自己写分页查询就行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: