MyBatis version

3.4.5

Database vendor and version

mysql 5.7+

Test case or example project

deserialize data in table test to POJO Test using mybatis mapper.xml.

create table test {
    `id` bigint pk,
    `names` json
}
//POJO Test    
class Test {
    private long id;
    public void setId(long id) {
        this.id = id;
    }
    private List<String> names;
    public void setNames(List<String> names) {
        this.names = names;
    }
}

// typehandler use jackson for deserialization 
// the clazz in constructor lost actualTypeArguments when real class is ParameterizedType
class JsonTypeHandler<T>(private var clazz: Class<T>) : BaseTypeHandler<T>() {

    protected val objectMapper = ObjectMapper()

    override fun setNonNullParameter(ps: PreparedStatement?, i: Int, parameter: T, jdbcType: JdbcType?) {
        ps?.setString(i, this.toJson(parameter))
    }

    private fun toJson(obj: T): String {
        try {
            return this.objectMapper.writeValueAsString(obj)
        } catch (e: Exception) {
            throw RuntimeException(e);
        }
    }
    <resultMap id="testMapper" type="Test">
        <result property="id" column="id" />
        <result property="names" column="names" 
                typeHandler="JsonTypeHandler"/>
    </resultMap>

After debug the source code of mybatis, the class in the constructor of TypeHandler is get from org.apache.ibatis.reflection.Reflector#setTypes. But when the type is ParameterizedType to be added, ignore the actualTypeArguments and only add rawType. ```java //org.apache.ibatis.reflection.Reflector private void addSetMethod(String name, Method method) { if (isValidPropertyName(name)) { setMethods.put(name, new MethodInvoker(method)); Type[] paramTypes = TypeParameterResolver.resolveParamTypes(method, type); setTypes.put(name, typeToClass(paramTypes[0])); } }

private Class<?> typeToClass(Type src) { Class<?> result = null; if (src instanceof Class) { result = (Class<?>) src; } else if (src instanceof ParameterizedType) { // ignore the actualTypeArguments and only add rawType. result = (Class<?>) ((ParameterizedType) src).getRawType(); } ... } return result; } ```

Expected result

TypeHandler need to get the real ParameterizedType. Otherwise, I need to write many useless code to create many class inherit TypeHandler to pass the ParameterizedType manual.

Actual result

TypeHandler lost information of actualTypeArguments when class is ParameterizedType

Comment From: DavidTangWei

@harawata hi. Why do TypeHandler ignore the actualTypeArguments when the type is ParameterizedType? Do you have plan to give us another method to get the actualTypeArguments. I need your help! Please reply, thanks!

Comment From: harawata

Hello @DavidTangWei ,

It is a known limitation. I have been working on a patch, but it requires a lot of changes and I don't have much free time recently.

Comment From: wyl0706

@harawata I am experiencing the same problem, is there a plan to complete it? My problem link: https://stackoverflow.com/questions/69140073/how-to-use-generics-in-mybatis-jsontypehandler

Comment From: harawata

@wyl0706 There will be a new comment when/if there is any news. :)

Comment From: half-dead

@harawata any update on this issue?

Comment From: FlyInWind1

I am trying to work on this https://github.com/FlyInWind1/mybatis-3

Comment From: FlyInWind1

I have impl ListTypeHandler. I pass ResolvedType (wrap jackson JavaType) to TypeHandler, instead of Class. link https://github.com/FlyInWind1/mybatis-3 And this is my mybatis-plus https://github.com/FlyInWind1/mybatis-plus

Comment From: bunnyblueair

any update on this issue?

Comment From: gr0l

Any updates on this issue?

Comment From: la3rence

Any update on this?

Comment From: Jasonyou-boy

Is there any update?I had the same problem

Comment From: Vzhangs

Any updates on this? I want to create a common List TypeHandler for a PostgreSQL composite type array column. But it might not be possible to implement it without getting the actualTypeArguments.

Comment From: harawata

Hi all,

I have submitted #3379 . It's still "draft", but I would appreciate if you could test your own usage against #3379 . If you found a problem, please create/share a test case.