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

 

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