org.apache.ibatis.type.TypeException: Error setting non null for parameter #4 with JdbcType null

preface

        The spring boot project uses the mybatis plus framework.

Phenomenon

        When I used mappr to execute the method updatebyid again, the following error occurred

nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='et.props', mode=IN, javaType=class java.lang.Object, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #4 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #4 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.postgresql.util.PSQLException: No hstore extension installed.
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='et.props', mode=IN, javaType=class java.lang.Object, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #4 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #4 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.postgresql.util.PSQLException: No hstore extension installed.

Problem location

        Through the literal meaning of the exception, we can understand it as a mybatis type error.

        Following up with debug, we found that an exception occurred when setting typehandler for one of the fields, indicating that there is no type that can identify the field.

  Cause analysis

        We now check the type of this field in the entity class and find that it is a map type

          View the type of this field setting in the database  , You can see that the JSON type is stored in the database

  Solution

        Set typehandler and JDBC type for entity class

@TableField(el = "props,jdbcType=OTHER,typeHandler=com.embracesource.cloud.fsgw.entity.HashMapJsonTypeHandler")
private Map<String, Object> props;

        Hashmapjsontypehandler class

import com.alibaba.fastjson.JSON;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.postgresql.util.PGobject;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class HashMapJsonTypeHandler extends BaseTypeHandler<Map<String,Object>> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Map<String,Object> parameter,
                                    JdbcType jdbcType) throws SQLException {
        PGobject jsonObject = new PGobject();
        jsonObject.setType("json");
        jsonObject.setValue(JSON.toJSONString(parameter));
        ps.setObject(i, jsonObject);
    }

    @Override
    public Map<String,Object> getNullableResult(ResultSet rs, String columnName)
            throws SQLException {

        return JSON.parseObject(rs.getString(columnName), HashMap.class);
    }

    @Override
    public Map<String,Object> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {

        return JSON.parseObject(rs.getString(columnIndex), HashMap.class);
    }

    @Override
    public Map<String,Object> getNullableResult(CallableStatement cs, int columnIndex)
            throws SQLException {

        return JSON.parseObject(cs.getString(columnIndex), HashMap.class);
    }
}

         Start the project again and find the problem to be solved


Read More: