Type handler was null on parameter mapping for property 'version'

Question

我在程序里设置了Version对应的TypeHandler,但是在运行的时候却老是报错:Type handler was null on parameter mapping for property 'version'

VersionTypeHandler.groovy

@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(Version.class)
class VersionTypeHandler extends BaseTypeHandler<Version> {
    @Override
    void setNonNullParameter(PreparedStatement ps, int i, Version v, JdbcType jdbcType) throws SQLException {
        ps.setString(i, v.toString())
    }

    @Override
    Version getNullableResult(ResultSet rs, String columnName) throws SQLException {
        def value = rs.getString(columnName)
        return Version.from(value)
    }

    @Override
    Version getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        def value = rs.getString(columnIndex)
        return Version.from(value)
    }

    @Override
    Version getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        def value = cs.getString(columnIndex)
        return Version.from(value)
    }
}

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <package name="com.xxx.core.domain"/>
        <package name="com.xxx.admin.domain"/>
    </typeAliases>

    <typeHandlers>
        <typeHandler handler="com.xxx.core.mybatis.ImagesTypeHandler"/>
        <typeHandler handler="com.xxx.core.mybatis.PricesTypeHandler"/>
        <typeHandler handler="com.xxx.core.mybatis.BoughtsTypeHandler"/>
        <typeHandler handler="com.xxx.core.mybatis.VersionTypeHandler"/>
        <typeHandler handler="com.xxx.core.mybatis.MessageDataHandler"/>
    </typeHandlers>

    <plugins>
        <plugin interceptor="com.xxx.core.mybatis.StatsInterceptor"/>
    </plugins>

    <mappers>
        <package name="com.xxx.core.mapper"/>
        <package name="com.xxx.admin.mapper"/>
    </mappers>

</configuration>

Answer

通过Google搜索了一圈,发现并不能解决我目前遇到的问题,于是就跑到MyBatis官方文档去看,详细一看之后发现了问题:

When deciding which TypeHandler to use in a ResultMap, the Java type is known (from the result type), but the JDBC type is unknown. MyBatis therefore uses the combination javaType=[TheJavaType], jdbcType=null to choose a TypeHandler. This means that using a @MappedJdbcTypes annotation restricts the scope of a TypeHandler and makes it unavailable for use in ResultMaps unless explicity set. To make a TypeHandler available for use in a ResultMap, set includeNullJdbcType=true on the @MappedJdbcTypes annotation. Since Mybatis 3.4.0 however, if a single TypeHandler is registered to handle a Java type, it will be used by default in ResultMaps using this Java type (i.e. even without includeNullJdbcType=true).

文档其实说得很明确了,只需要添加includeNullJdbcType=true这个属性就可以解决。但是v3.4.0以后,就不需要显式的添加这个属性了。

修改之后的VersionTypeHandler.groovy

@MappedJdbcTypes(value=JdbcType.VARCHAR, includeNullJdbcType = true)
@MappedTypes(Version.class)
class VersionTypeHandler extends BaseTypeHandler<Version> {
    @Override
    void setNonNullParameter(PreparedStatement ps, int i, Version v, JdbcType jdbcType) throws SQLException {
        ps.setString(i, v.toString())
    }

    @Override
    Version getNullableResult(ResultSet rs, String columnName) throws SQLException {
        def value = rs.getString(columnName)
        return Version.from(value)
    }

    @Override
    Version getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        def value = rs.getString(columnIndex)
        return Version.from(value)
    }

    @Override
    Version getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        def value = cs.getString(columnIndex)
        return Version.from(value)
    }
}

results matching ""

    No results matching ""