追記@2017-07-02
下記Issueで既に対応していただいています。次のバージョン(3.4.5)に入る予定です。
MyBatisのSQLへのパラメータ埋め込みで、size
という名前を使うと、JavaTypeがintとなってしまうようです。
現象を確認したのは、mybatis-spring-boot-starter
の1.3.0(MyBatis自体のバージョンは3.4.4)です。
問題となるコード
下記のようなMapperを作ります。size
という名前で、long型の引数をマッピングします。
package com.example.demo; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; @Repository @Mapper public interface TestRepository { @Insert("INSERT INTO test(number, size) VALUES(#{number}, #{size})") public void insert(@Param("number") long number, @Param("size") long size); }
上記のメソッドを呼び出すと、下記のようなエラーが発生します。
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='size', mode=IN, javaType=int, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #2 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
なぜかsize
がintとしてマッピングされようとしてClassCastExceptionが発生しています。LongTypeHandler
が使われるべきなのに、IntTypeHandler
が使用されてしまっているようです。
試しに下記のように別の名前に変えるとうまく動作します。
@Insert("INSERT INTO test(number, size) VALUES(#{number}, #{size2})") public void insert2(@Param("number") long number, @Param("size2") long size);
size
という名前は、何か特別なものとして使われていて、それと競合することによっておきてしまっているのかもしれません。