MyBatis version
3.5.5
Database vendor and version
mysql 8.0
Test case or example project
as follow,resultMap has result column = d.id Mapping sysDepartment.Id
<resultMap id="listMap" type="SysUser ">
<result column="u.id" property="id"/>
<result column="DepartmentId" property="departmentId"/>
<association property="sysDepartment" javaType="SysDepartment">
<result column="d.id" property="id"/>
</ association>
</ resultMap>
<select id="list" resultMap="listMap">
select u.* ,d.* from SysUser u left join SysDepartment d on d.Id = u.departmentId
</select>
as follow,in source code class DefaultColumnDefinition, the fullColumnNameToIndex field contains d.id column.so Under normal conditions, column = d.id can Mapping sysDepartment.Id.
as follow,in class method DefaultResultSetHandler.createRowKeyForMappedProperties,because mappedColumnNames not contains d.id,so code final Object value = th.getResult(rsw.getResultSet(), column) can not excute. this cause column = d.id can not Mapping sysDepartment.Id.
Expected result
resultMap has result **column = d.id column = d.id can Mapping sysDepartment.Id
Actual result
resultMap has result **column = d.id column = d.id can not Mapping sysDepartment.Id
how to fix
DefaultResultSetHandler(class).createRowKeyForMappedProperties(method).mappedColumnNames(field) cotains d.id column just like DefaultColumnDefinition(class).findColumn(method).columnToIndexCache(field)
Comment From: harawata
Hello, @g5zhu5896 .
Column labels don't include table names i.e. both u.id
and d.id
will have the same column label id
in the result set.
You have to use column alias to distinguish them (it's not a MyBatis issue, but a common JDBC/SQL limitation, by the way).
select u.*, d.id as d_id from ...
<association ...>
<id column="d_id" property="id" />
It might be better to define a separate result map for SysDepartment
and reference it with columnPrefix
.
https://mybatis.org/mybatis-3/sqlmap-xml.html#Nested_Results_for_Association
p.s. Please use text instead of image so that I can copy & paste 🙏
Comment From: g5zhu5896
Hello, @g5zhu5896 .
Column labels don't include table names i.e. both
u.id
andd.id
will have the same column labelid
in the result set. You have to use column alias to distinguish them (it's not a MyBatis issue, but a common JDBC/SQL limitation, by the way).
sql select u.*, d.id as d_id from ...
<association ...> <id column="d_id" property="id" />
It might be better to define a separate result map for
SysDepartment
and reference it withcolumnPrefix
. https://mybatis.org/mybatis-3/sqlmap-xml.html#Nested_Results_for_Associationp.s. Please use text instead of image so that I can copy & paste 🙏
but in the source code, class DefaultColumnDefinition.findColumn.fullColumnNameToIndex(used to mapping result set.) contains table names i.e. both u.id and d.id column, if the source code DefaultResultSetHandler(class).createRowKeyForMappedProperties(method).mappedColumnNames (field) also contains d.id and u.id, Column labels will be able include table names i.e. both u.id and d.id . I tried and successfully
Comment From: harawata
MyBatis cannot use DefaultColumnDefinition
because it is MySQL specific class and is not part of JDBC API.
Comment From: g5zhu5896
MyBatis cannot use
DefaultColumnDefinition
because it is MySQL specific class and is not part of JDBC API.
but DefaultResultSetHandler
is part of Mybatis, let DefaultResultSetHandler(class).createRowKeyForMappedProperties(method).mappedColumnNames(List field)
contains d.id
and u.id
,
Column labels will be able include table names i.e. both u.id
and d.id
,at least in mysql.
if not part of JDBC API
means in other database is Different(not contains u.id
and d.id
),Forget it.
Comment From: harawata
I did quick test. A few drivers (mysql, mariadb, pgjdbc) support it, but others (e.g. mssql, oracle, h2, hsqldb) don't. Closing.