成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【踩坑實(shí)錄】Hibernate報(bào)錯(cuò)node to traverse cannot be null排查

hsluoyz / 495人閱讀

最近在改一份二手代碼的時(shí)候,項(xiàng)目運(yùn)行報(bào)了個(gè)java.lang.IllegalArgumentException: node to traverse cannot be null異常。
WTF?!難道我HQL寫錯(cuò)了?!我只是添加了一個(gè)update方法而已?。?/p> 問題排查:


這里使用的是JPA的Query注解,其實(shí)語法跟HQL是一樣的,我已經(jīng)把這行HQL每個(gè)空格都TM檢查過了,沒有發(fā)現(xiàn)任何奇怪的東西,沒辦法了只好調(diào)試一下源碼


最先拋出異常的是在Hibernate的orghibernatehqlinternalastutilNodeTraverser.java:46,這里判斷如果AST為空,則拋出異常,那AST到底是個(gè)啥啊?

通過跟蹤NodeTraverser的調(diào)用,可看到ACT是從parser獲取的,而這里的parser實(shí)際上就是Hibernate的Hql語法分析器!因此網(wǎng)上很多文章都會(huì)得出本文提到的異常就是HQL語法錯(cuò)誤導(dǎo)致的了。但是我這個(gè)HQL明顯沒有語法錯(cuò)誤的,問題又出在哪呢?我們加個(gè)短點(diǎn)瞧一瞧:

好玩的事情來了,如果HQL是select開頭的話,是不會(huì)報(bào)錯(cuò)的

等到一條update了,果然parser處理后的hqlAst是空的對(duì)比上面Select語句就可以明顯看出問題所在了:?jiǎn)栴}出在了parser.statement()里,那跟進(jìn)去看看囖:

逐行調(diào)試,發(fā)現(xiàn)在執(zhí)行updateStatement()時(shí)拋出異常,再跟進(jìn)去:

跑到default去了


因?yàn)長(zhǎng)A(1)是41,不在switch的任何分支里,然后實(shí)際上我在這花了很多時(shí)間,都浪費(fèi)在看antrl的源碼上了,就是想搞明白LA是在那里設(shè)值的,結(jié)果越看越懵逼,但實(shí)際上我們可以換個(gè)思路,通過監(jiān)控每一步執(zhí)行后的各個(gè)變量可以發(fā)現(xiàn)有這樣的規(guī)律:


上圖是在執(zhí)行match(UPDATE)前,各個(gè)主要變量如圖所示


直到執(zhí)行了match方法后,LA(1)變?yōu)榱?1,而同時(shí),LT(1)里的值引起了我的注意:
上面已經(jīng)提到過了,實(shí)際上這部分代碼是Hibernate的HQL語法解析器,那講道理的話,第一次執(zhí)行,處理完UPDATE關(guān)鍵字,往后應(yīng)該是第二個(gè)關(guān)鍵字,而實(shí)際上我們的HQL中根被沒有order這個(gè)詞啊,為什么會(huì)導(dǎo)致報(bào)錯(cuò)呢?
還記得上面的某個(gè)斷點(diǎn)么,就是調(diào)用parser.statement()的地方,來看看交由parser處理時(shí)的hql是什么樣子的


你們發(fā)現(xiàn)問題了嗎?Hibernate在處理hql的時(shí)候,是會(huì)把包名補(bǔ)全的,而這個(gè)實(shí)體類的包名是以order開頭的!update關(guān)鍵字后不能有order關(guān)鍵字...

最后我把實(shí)體類的包重構(gòu)了!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76583.html

相關(guān)文章

  • 踩坑記[持續(xù)更新]

    摘要:解決的中只有一個(gè)生命周期的鉤子也只有一句代碼報(bào)錯(cuò)中的就是整個(gè)組建中的原來是寫在了使用指令的后面所以此時(shí)還沒有在組件中注冊(cè)所以會(huì)報(bào)錯(cuò)誤正確代碼標(biāo)題這是一段內(nèi)容這是一段內(nèi)容這是一段內(nèi)容這是一段內(nèi)容。 用于記錄coding過程中遇到的比較難解決或者有意思的問題,包括前端/后端(Node/Db),會(huì)持續(xù)更新... 后端 Node redis集群模式下pipline報(bào)錯(cuò)(2019.3.14) ...

    0x584a 評(píng)論0 收藏0
  • 踩坑記[持續(xù)更新]

    摘要:解決的中只有一個(gè)生命周期的鉤子也只有一句代碼報(bào)錯(cuò)中的就是整個(gè)組建中的原來是寫在了使用指令的后面所以此時(shí)還沒有在組件中注冊(cè)所以會(huì)報(bào)錯(cuò)誤正確代碼標(biāo)題這是一段內(nèi)容這是一段內(nèi)容這是一段內(nèi)容這是一段內(nèi)容。 用于記錄coding過程中遇到的比較難解決或者有意思的問題,包括前端/后端(Node/Db),會(huì)持續(xù)更新... 后端 Node redis集群模式下pipline報(bào)錯(cuò)(2019.3.14) ...

    ckllj 評(píng)論0 收藏0
  • JavaScript數(shù)據(jù)結(jié)構(gòu):樹

    摘要:第二步自終止,第三步自調(diào)用,第四步回調(diào)函數(shù)會(huì)重復(fù)進(jìn)行,直到我們遍歷到樹的所有節(jié)點(diǎn)。執(zhí)行回調(diào)函數(shù),傳入賦值為第二層第二個(gè)子節(jié)點(diǎn)。 本文譯自Cho S. Kim的文章:Data Structures With JavaScript: Tree 樹,是web開發(fā)中最常用的數(shù)據(jù)結(jié)構(gòu)之一。這句話對(duì)開發(fā)者和用戶來講,都適用:開發(fā)人員通過HTML創(chuàng)造了一個(gè)DOM,用戶則通過DOM消費(fèi)網(wǎng)絡(luò)信息。 ...

    LeoHsiun 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<