javaspringmybatisspring-mybatistypehandler

Mybatis null configuration object inside custom TypeHandler


I was writing a custom JsonTypeHandler, code works fine but I wanted access to configuration field of extended BaseTypeHandler which seems always null. Why is it null? Am I missing something here?

null configuration debug image

Custom JsonTypeHandler: You may ignore methods inside below code.

@MappedTypes({ JsonObject.class })
@MappedJdbcTypes({JdbcType.NVARCHAR})
public class JsonTypeHandler extends BaseTypeHandler<JsonObject> {

    private String sqlDialect;

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, JsonObject parameter, JdbcType jdbcType)
            throws SQLException {
        String parameterAsString = new Gson().toJson(parameter, JsonObject.class);
            ps.setString(i, parameterAsString);
    }

    @Override
    public JsonObject getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String sqlJson = rs.getString(columnName);
        if (null != sqlJson) {
            return new Gson().fromJson(sqlJson, JsonObject.class);
        }
        return null;
    }

    @Override
    public JsonObject getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String sqlJson = rs.getString(columnIndex);
        if (null != sqlJson) {
            return new Gson().fromJson(sqlJson, JsonObject.class);
        }
        return null;
    }

    @Override
    public JsonObject getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String sqlJson = cs.getString(columnIndex);
        if (null != sqlJson) {
            return new Gson().fromJson(sqlJson, JsonObject.class);
        }
        return null;
    }
}

mybatis-config.xml

<configuration>
    <settings>
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="jdbcTypeForNull" value="NULL"/>
    </settings>

    <typeHandlers>
        <typeHandler handler="com.dummy.JsonTypeHandler" javaType="com.google.gson.JsonObject"/>
    </typeHandlers>

    <databaseIdProvider type="DB_VENDOR">
        <property name="PostgreSql" value="postgres"></property>
    </databaseIdProvider>

    <mappers>
        <!--mappers-->
    </mappers>
</configuration>

spring-context.xml

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation"
                  value="classpath:com/dummy/mybatis/mybatis-config.xml"/>
        <property name="dataSource" ref="postgresDataSource"/>
</bean>

Versions:

dependency 'org.mybatis:mybatis:3.4.1'
mavenBom 'org.springframework:spring-framework-bom:5.2.6.RELEASE'

My intention is to get databaseId from configuration object inside BaseTypeHandler. Hope snippets are reproducible.


Solution

  • As explained in this issue, the field BaseTypeHandler.configuration is added by mistake and is planned to be removed.

    You can register an instance of the type handler after setting necessary properties instead of registering the Class. It would look something like this:

    JsonTypeHandler handler = new JsonTypeHandler(configuration);
    configuration.getTypeHandlerRegistry().register(..., handler, ...);