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,配合分页参数自己写分页查询就行。
因为业务逻辑上的问题,项目写到前几天突然发现要重新设计数据库某个表的主键。(在团队同学的建议下),采用了之前一直没机会接触过的联合主键。
项目用的是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,配合分页参数自己写分页查询就行。
相关文章推荐
- spring-data-jpa——如果使用了one-to-many,many-to-one的注解,在Jackson进行json字符串化时出现错误的解决方案
- spring jpa使用联合主键
- Spring Data JPA使用复合主键
- spring-data-jpa 中,如果使用了one-to-many , many-to-one的注释,会在Jackson进行json字符串化的时候出现错误
- Spring Data JPA使用复合主键
- 通过JPA注解映射视图的实体类 jpa 视图 无主键 @Query注解的用法(Spring Data JPA) jpa 使用sql语句
- spring-data-jpa 中,如果使用了one-to-many , many-to-one的注释,会在Jackson进行json字符串化的时候出现错误
- 使用 Spring Data JPA 简化 JPA 开发
- 使用 Spring Data JPA 简化 JPA 开发
- Spring Data JPA 初使用
- 使用 Spring Data JPA 简化 JPA 开发
- 使用 Spring Data JPA 简化 JPA 开发
- (入门帖)使用 Spring Data JPA 简化 JPA 开发
- Spring Data JPA 初使用
- Spring Data JPA 初使用
- Spring Data JPA 初使用
- 使用 Spring Data JPA 简化 JPA 开发
- Spring-Data-Jpa出现的问题
- spring-data-jpa 使用
- Spring Data JPA的简单使用