MyBatis使用@Param搭配EnumOrdinalTypeHandler报错排查与解决
MyBatis使用@Param注解时枚举类型处理器初始化失败的问题解决
问题场景
MyBatis版本:3.5.11
编写了以下两个插入方法:
@Insert({ "insert into ENUMORDINALTEST (ID, NAME)", "values (#{row.id,jdbcType=INTEGER}, #{row.name,jdbcType=INTEGER,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler})" }) int insert(@Param("row") Enumordinaltest row); @Insert({ "insert into ENUMORDINALTEST (ID, NAME)", "values (#{id,jdbcType=INTEGER}, #{name,jdbcType=INTEGER,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler})" }) int insert(Enumordinaltest row);
使用带@Param("row")的方法时,MyBatis抛出错误:
Caused by: org.apache.ibatis.type.TypeException: Failed invoking constructor for handler class org.apache.ibatis.type.EnumOrdinalTypeHandler
不使用@Param注解时方法可正常执行。其中Enumordinaltest类包含枚举字段TestEnum:
public enum TestEnum { FRED, WILMA, BARNEY, BETTY }
调试分析
调试MyBatis源码发现,处理row.name时无法获取对应的javaType,在buildParameterMapping方法中,最终javaType被设为Object.class,导致类型处理器初始化失败。
解决方法
在#{row.name}的参数配置中显式指定javaType为对应的枚举类后,问题解决:
@Insert({ "insert into ENUMORDINALTEST (ID, NAME)", "values (#{row.id,jdbcType=INTEGER}, #{row.name,javaType=com.xxx.wec.demo.dal.TestEnum, jdbcType=INTEGER,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler})" }) int insert(@Param("row") Enumordinaltest row);
内容的提问来源于stack exchange,提问作者qijun
相关产品推荐
相关产品推荐

