org.h2.jdbc.JdbcSQLDataException: Value too long for column """xxx"" ENUM('x1', 'x2')": "

現象

更新money字段的值sql,卻報too long for column "type",其實更新語句不涉及type字段,但問題在這裏。

有遇到類似問題的,接下來對號入座。

出現這這個問題,有以下幾種情形:

1. java定義type字段是int類型

2. db中這個字段是enum類型

3. 插入和查詢時這個字段是沒有問題的

4. 更新這個字段沒有問題

5. 更新別的字段的同時沒有更新這個字段,就出問題了,如果更新過這個字段問題解決,下次重啓,問題復現

6. 用的h2數據庫

原因

翻了下出問題異常堆棧的時候,在一個方法上看到這個註釋:

這裏可以看出,即使更新一個字段也會處理所有列。。。雖然更新的時候沒有這個字段,依然會處理下。

拋異常的地方在這裏:value是int類型,value的precision的值是10,參數precision的值是7(應該是按‘complex'的長度計算的,即enum的最大字段的長度)。這裏判斷value的precision過大,不合法,就異常了。

而type列的值是0或1,一個整數類型。在後面有個精度計算判斷的時候,int的爲10,而這個enum類型的type列的精度爲7,不合法了。就拋這個異常了。

出現type列爲Int類型的原因看下圖,在Page.read(buff, pos, map)方法內,後面有很多操作,就不一一截圖了。我花了大晚上時間翻這塊代碼,搞清楚它這個反序列化過程(先key,然後是values,在處理values時把一行的每一個列依次反序列化,buff裏保存了很多信息比如類型,值什麼的,有它自己的編解碼方式)。在初始化的時候計算的這個type column的信息就是enum,但是這裏反序列化出來的類型信息,如果是enum或int都按int處理,返回的就是值的角標。

這是h2自己加載數據的時候,反序列化的7個字段中,type直接就是ValueInt,尷尬了。

因此,我發現了個很尷尬的問題,它自己取的列屬性是enum,反序列出來的值類型是int。這裏是它引擎自己的事,和框架無關。

解決辦法

沒有找資料看別人怎麼弄,不過看源代碼這裏找到了出現原因和問題所在,我先考慮從代碼層面嘗試解決,按規範定義java bean,把這個字段定義爲enum類型映射,明知道其實和這個關係不大(即使直接執行原生sql也是這問題),還想試下。

果然,重啓之後,結果還是報這個錯。

然後,想着把db中enum的字段字義改長點,超過10位,如:

alter table T_VIP_USERS alter column type set data type enum('complex_card', 'haircut_card') ;

測試更新money卻報type字段 too long這個問題已經沒有了,,,然後測試了下代碼的插入操作也沒有問題了。只是覺得這個問題解決的很尷尬,不像正道。。。

 

 

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