Closed
Description
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
.
//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
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
DavidTangWei commentedon Mar 10, 2021
@harawata hi.
Why do TypeHandler ignore the
actualTypeArguments
when the type isParameterizedType
? Do you have plan to give us another method to get theactualTypeArguments
.I need your help! Please reply, thanks!
harawata commentedon Mar 10, 2021
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.
wyl0706 commentedon Sep 12, 2021
@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
harawata commentedon Sep 13, 2021
@wyl0706 There will be a new comment when/if there is any news. :)
half-dead commentedon Sep 29, 2022
@harawata any update on this issue?
FlyInWind1 commentedon Nov 26, 2022
I am trying to work on this https://github.com/FlyInWind1/mybatis-3
FlyInWind1 commentedon Dec 7, 2022
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
bunnyblueair commentedon Mar 23, 2023
any update on this issue?
gr0l commentedon Oct 23, 2023
Any updates on this issue?
la3rence commentedon Apr 26, 2024
Any update on this?
Jasonyou-boy commentedon May 18, 2024
Is there any update?I had the same problem
Vzhangs commentedon Jul 27, 2024
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.
java.lang.reflect.Type
instead ofClass
and respect runtime JDBC type #3379harawata commentedon Jan 3, 2025
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.
harawata commentedon Mar 15, 2025
#3379 is merged.
Please test 3.6.0-SNAPSHOT with your apps and give us feedback.
There have been A LOT of other changes as well.