jpa或者hibernate源码分析之Unable to locate appropriate constructor

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章