動態

詳情 返回 返回

mybatis升級到3.4.5後導致的偽bug - 動態 詳情

關鍵詞: mybatis、foreach、foreach context scope、MyBatis3.4.5、BindingException

背景:
隨着團隊開發人數越來越多,項目迭代越來越久,加上一些半吊子開發的盲目自信,項目如果不夠健壯,就會出現莫名其妙的問題,甚至讓測試團隊對某些開發一瞬間喪失全部信任。

起因是團隊有150多個服務的分佈式微服務項目,服務之間有RPC調用關係,也有公共組件庫,基礎類庫的交叉引用關係,甚至部分服務提供門面接口,通過maven jar將接口抽象給其他服務提供者使用,自身只實現接口,作為RPC提供者,提供數據。

隨着項目迭代,開發引入jar的時候直接去maven 中央倉庫搜索座標,也不關心跟項目中其他依賴的版本對照關係,直接將座標引入pom.xml中, 由於服務之間有公共jar的相互依賴,公共jar會將一些依賴傳遞過去,攜帶到服務依賴中,久而久之,就會造成依賴衝突,甚至出現幻影依賴,知道某個成員用到了介於兩個版本之間的API時,問題爆發。

項目中有這麼一段遠古 mybatis xml代碼
image.png

在這段代碼中,list的每一批數據,每批數據的plan_id屬性都是相同的,plan_idid是一對多的關係

在mybatis 3.4.5之前,這段代碼的寫法“恰好”沒有問題,因為foreach標籤中的item作用域是全局,#{item.plan_id, jdbcType=BIGINT}剛好取到了循環id時的最後一個item

由於項目依賴衝突,糾正mybatis依賴

  1. 按照Spring boot版本找mybatis-spring-boot-starter
  2. 找到mybatis-spring-boot-starter中依賴的spring-boot-starter的版本>=當前項目的spring-boot-starter的版本,注意不能跨大版本,例如spring-boot-starter 2.1.x都可以,小版本無影響
  3. 此時mybatis-spring-boot-starter中傳遞的mybatis版本就是最佳的

由於正好最合適的mybatis版本是3.4.6,之前的版本一直是3.4.2,遇到了這個問題,報錯:
BindingException: Parameter: 'xxx' not found. Available parameters are [list, param1]

由於我本人非常熟悉MyBatis的源碼,這個問題一下就猜到,直接將根本原因找出來

  • MyBatis bug issue
  • MyBatis release v3.4.5

最後,告誡各位寫代碼時遵循以下幾點

  1. 寫代碼一定要寫健壯性強的代碼,不給自己留坑,也不給別人挖坑
  2. 每寫一行代碼,一個函數,一個類,做到無IDE警告,必要時使用@SuppressWarnings壓制
  3. 調用三方庫、三方組件時多思考,多看源碼,不寫有歧義的代碼
  4. 自己封裝函數前,先考慮有沒有可靠庫可以使用,例如guavacommons-lang
user avatar king_wenzhinan 頭像 journey_64224c9377fd5 頭像 debuginn 頭像 seazhan 頭像 AmbitionGarden 頭像 u_16769727 頭像 u_11365552 頭像 u_15702012 頭像 ahahan 頭像 lenve 頭像 lu_lu 頭像 nianqingyouweidenangua 頭像
點贊 41 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.