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