最近在改一份二手代碼的時候,項目運行報了個java.lang.IllegalArgumentException: node to traverse cannot be null異常。
WTF?!難道我HQL寫錯了?!我只是添加了一個update方法而已啊!
這里使用的是JPA的Query注解,其實語法跟HQL是一樣的,我已經把這行HQL每個空格都TM檢查過了,沒有發現任何奇怪的東西,沒辦法了只好調試一下源碼
最先拋出異常的是在Hibernate的orghibernatehqlinternalastutilNodeTraverser.java:46,這里判斷如果AST為空,則拋出異常,那AST到底是個啥啊?
通過跟蹤NodeTraverser的調用,可看到ACT是從parser獲取的,而這里的parser實際上就是Hibernate的Hql語法分析器!因此網上很多文章都會得出本文提到的異常就是HQL語法錯誤導致的了。但是我這個HQL明顯沒有語法錯誤的,問題又出在哪呢?我們加個短點瞧一瞧:
好玩的事情來了,如果HQL是select開頭的話,是不會報錯的
等到一條update了,果然parser處理后的hqlAst是空的對比上面Select語句就可以明顯看出問題所在了:問題出在了parser.statement()里,那跟進去看看囖:
逐行調試,發現在執行updateStatement()時拋出異常,再跟進去:
跑到default去了
因為LA(1)是41,不在switch的任何分支里,然后實際上我在這花了很多時間,都浪費在看antrl的源碼上了,就是想搞明白LA是在那里設值的,結果越看越懵逼,但實際上我們可以換個思路,通過監控每一步執行后的各個變量可以發現有這樣的規律:
上圖是在執行match(UPDATE)前,各個主要變量如圖所示
直到執行了match方法后,LA(1)變為了41,而同時,LT(1)里的值引起了我的注意:
上面已經提到過了,實際上這部分代碼是Hibernate的HQL語法解析器,那講道理的話,第一次執行,處理完UPDATE關鍵字,往后應該是第二個關鍵字,而實際上我們的HQL中根被沒有order這個詞啊,為什么會導致報錯呢?
還記得上面的某個斷點么,就是調用parser.statement()的地方,來看看交由parser處理時的hql是什么樣子的
你們發現問題了嗎?Hibernate在處理hql的時候,是會把包名補全的,而這個實體類的包名是以order開頭的!update關鍵字后不能有order關鍵字...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/76583.html
摘要:第二步自終止,第三步自調用,第四步回調函數會重復進行,直到我們遍歷到樹的所有節點。執行回調函數,傳入賦值為第二層第二個子節點。 本文譯自Cho S. Kim的文章:Data Structures With JavaScript: Tree 樹,是web開發中最常用的數據結構之一。這句話對開發者和用戶來講,都適用:開發人員通過HTML創造了一個DOM,用戶則通過DOM消費網絡信息。 ...
閱讀 3878·2021-07-28 18:10
閱讀 2589·2019-08-30 15:44
閱讀 1099·2019-08-30 14:07
閱讀 3469·2019-08-29 17:20
閱讀 1587·2019-08-26 18:35
閱讀 3545·2019-08-26 13:42
閱讀 1827·2019-08-26 11:58
閱讀 1603·2019-08-23 18:33