org.hibernate.hql.internal.ast.DetailedSemanticException: Unable to locate appropriate constructor on class
背景
一次维护别人未开发完成的项目,做下之前的查询接口测试,发现报上面的错误。然后第一时间百度,很遗憾百度这次让我失望了,
没有搜索出我想要的答案。于是不断的debug去到最底层看看发生了什么。
这个查询接口主要是jpa自定义VO来接收多表查询关联出来的数据。
首先在hibernate 中 一个比较重要的类是HqlSqlWalker 里面有个方法processConstructor方法。
至于我是怎么找到的,我是 通过一直debug这个方法entityManager.createQuery 往下找的。
上图的prepare发生了什么 如下图所示
上图最关键的一行代码是
Class[] params = candidate.getParameterTypes();
有什么用?是获取一个类的构造方法里面的所有参数的类型。
比如有个类里面有个属性是 private String name; 且这个类含有这个字段的构造函数,那么params这个数组返回的就是String
为什么hibernate要这样干呢。我们知道任何一种orm框架都有javaType sqlType这两个概念.需要数据库字段类型和java字段类型能匹配上. 这个匹配阶段发生在编译阶段。因此开文中的异常信息很明显是编译jpql造成的。还没到执行sql那一步就报错了。
之前的用来接收jpql查询语句返回的结果的VO如下所示 很明显这里只有一个@Data的lombok注解。这个注解是没有集成构造器的主键的.那么答案一目了然。
修改后的类如下 加上无参构造器和全参构造器
至此分析完毕!!!百度应该搜不到 原创!!!
如果有了全参构造器还有错误 参考下面4点即可!!!
1)参数构造器的参数类型是否正确
2)参数构造器的顺序和hql中的顺序是否一致
3)参数构造器的参数个数是否和hql中的个数一致
4)参数构造器的参数类型是否TimeStamp