Open Chishide opened 6 months ago
Hello @Chishide ,
I'm not sure. Please create a small demo project and share it on your GitHub repository. Here are some templates and examples: https://github.com/harawata/mybatis-issues
I think i have similar problem.
My example: postgres:12.4, mybatis 3.5.16 Table:
CREATE TABLE test_table (
id NUMERIC NOT NULL,
create_time TIMESTAMP(6)
)
Dto and mapping configuration:
package example;
import java.util.Date;
public class DbTestDto {
public DbTestDto() {}
public DbTestDto(Long id, Date createTime) {
this.id = id;
this.createTime = createTime;
}
private Long id;
private Date createTime;
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
package example;
import org.apache.ibatis.annotations.Param;
public interface DbTestDao {
void insert(@Param("dbTestDto") DbTestDto dbTestDto);
}
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE mapper PUBLIC '-//mybatis.org//DTD Mapper 3.0//EN'
'http://mybatis.org/dtd/mybatis-3-mapper.dtd'>
<mapper namespace='example.DbTestDao'>
<insert id="insert" parameterType="example.DbTestDto">
insert into TEST_TABLE (
id,
create_time
)
values (
#{dbTestDto.id},
#{dbTestDto.createTime}
)
</insert>
</mapper>
Problem: Until i specify javaType
in mapper (for example javaType=java.util.Date
for dbTestDto.createTime) javaType is resolved as java.lang.Object and org.apache.ibatis.type.UnknownTypeHandler is always used:
In my case i am not able to set javaType
, bacause i use some external library (which mybatis) without possibility to override.
I think that the problem is with org.apache.ibatis.reflection.MetaClass#hasGetter method in that case. On debug i see:
Check your's junit test org.apache.ibatis.reflection.MetaClassTest#shouldCheckGetterExistance
Simplest reproduction - debug org.apache.ibatis.submitted.keygen.Jdbc3KeyGeneratorTest and CountryMapper#insertNamedBean
Hmm.. Maybe it is impacted by difference between RawSqlSource and DynamicSqlSource (initialisation of sqlSource field)
I still don't understand what the expected/actual results are (because you guys ignored the issue report form). Is there an exception? Does the query insert an unexpected value?
And please stop using images unless it is absolutely necessary. Pasting debug window images is not helpful very much.
To fix a problem, we need to reproduce the problem first. The best way to show "how" is to create a small demo project. Here are some project templates and examples. https://github.com/harawata/mybatis-issues
Thank you!
The issue arises when using a custom save or update method where a Map is passed as the method's parameter, structured like this: { "param1" : POJO, "et" : POJO }
When MyBatis builds the BoundSql and creates the DynamicContext, it wraps the parameters again. This leads to a situation where, during the SQL parsing phase (org.apache.ibatis.builder.SqlSourceBuilder.ParameterMappingTokenHandler#buildParameterMapping), the correct propertyType cannot be obtained, which in turn prevents the deduction of the appropriate TypeHandler
the root cause lies here
our objectWrapper is MapWrapper. The property we're trying to access is "et.name", but the MapWrapper's internal map structure looks like this: { "_parameter" : {"param1" POJO, "et" : POJO}, "_databaseId" : null }
This happens because the DynamicContext wraps the parameters and constructs the MapWrapper
As a result, we cannot obtain the actual property getter return type. I hope this explanation is clear.
when the field's jdbcType is JSON (in Mysql). saving data results in errors. My current solution is specify the typeHandler xml: #{jsonField, typeHandler=com.yourpackage.JSONArrayTypeHandler}
Hello @DuDisv ,
Please read my previous comment. It would be really helpful if you could share an executable test case or demo project.
And, again, please do not use images when posting text information.
Thank you!
@harawata Hi , I have created a test demo project , project url When executing the updateUser method, the database reported an error.【Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.】
Thank you for the demo, @DuDisv !
I am now pretty sure that the reported problem is a known issue. I already wrote a patch that will address the issue, but it is targeted at v4 because the change is huge.
My patch is available in the following branch if you guys are interested. https://github.com/harawata/mybatis-3/tree/type-based-handler-resolution Feedback is welcome!
Thank you for your reply. I really appreciate it. @harawata
Hi all, in this case, this sql parsed with two params and mybatis wrap them as ParamMap type, when parsing the boud sql, the DynamicContext class wrap this ParamMap to ContexMap for binding field, ParameterMappingTokenHandler will deal the raw sql properties but can not get the correct property type because it the additionalParameters is wrapped can not get the value by propery, this property type will be recgonized as Object type, I know this can be work well with all most situations but in some case it will work wrong like enum field or customize field, is this a bug or can you give some adive?
MyBatis version
3.5.7
Database vendor and version
mysql
Test case or example project
Steps to reproduce
Expected result
Actual result