3.5.5
Oracle 12C
I've a test case which is working fine on Mybatis version 3.5.4
Here is my XML mapper
<?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="com.mycom.query.test">
<resultMap id="headerResultMap" type="com.mycom.query.test.TestHeader">
<constructor>
<idArg column="H_ID" javaType="_int" name="id"/>
</constructor>
<result property="field1" column="H_FIELD1"/>
<result property="field2" column="H_FIELD2"/>
<result property="field3" column="H_FIELD3"/>
</resultMap>
<resultMap id="detailResultMap" type="com.mycom.query.test.TestDetail">
<constructor>
<idArg column="D_ID" javaType="_int" name="id"/>
<idArg column="D_SEQ" javaType="_int" name="seq"/>
</constructor>
<result property="field1" column="D_FIELD1"/>
<result property="field2" column="D_FIELD2"/>
<result property="field3" column="D_FIELD3"/>
</resultMap>
<resultMap id="testResultMap" type="com.mycom.query.test.TestOrder">
<constructor>
<idArg resultMap="headerResultMap" javaType="com.mycom.query.test.TestHeader"/>
</constructor>
<collection property="details" ofType="com.mycom.query.test.TestDetail" resultMap="detailResultMap"/>
</resultMap>
<select id="find" resultMap="testResultMap">
SELECT
*
FROM (
SELECT
1 AS H_ID,
'H_FIELD1' AS H_FIELD1,
'H_FIELD2' AS H_FIELD2,
'H_FIELD3' AS H_FIELD3
FROM
DUAL
) H
LEFT JOIN (
SELECT
1 AS D_ID,
1 AS D_SEQ,
'D_FIELD1' AS D_FIELD1,
'D_FIELD2' AS D_FIELD2,
'D_FIELD3' AS D_FIELD3
FROM
DUAL
UNION ALL
SELECT
1 AS D_ID,
2 AS D_SEQ,
'D_FIELD4' AS D_FIELD1,
'D_FIELD5' AS D_FIELD2,
'D_FIELD6' AS D_FIELD3
FROM
DUAL
UNION ALL
SELECT
1 AS D_ID,
3 AS D_SEQ,
'D_FIELD7' AS D_FIELD1,
'D_FIELD8' AS D_FIELD2,
'D_FIELD9' AS D_FIELD3
FROM
DUAL
) D ON H.H_ID=D.D_ID
</select>
</mapper>
The result will produce one to many rows and map to my model
import java.util.List;
public class TestOrder {
private final TestHeader header;
private List<TestDetail> details;
public TestOrder(TestHeader header) {
this.header = header;
}
public TestHeader getHeader() {
return header;
}
public List<TestDetail> getDetails() {
return details;
}
public void setDetails(List<TestDetail> details) {
this.details = details;
}
@Override
public String toString() {
return getClass().getName() + "[header=" + header + ", details=" + details + ']';
}
}
Call using selectOne method, and I'm expect it will return 1 single object which is TestOrder. However, Mybatis 3.5.5 failed with message Expected one result (or null) to be returned by selectOne(), but found: 3
1 object with 3 details inside
Failed
Hello @vlcheong ,
Could you create and share an executable project like these on GitHub?
@harawata Here is my test
Thank you for the repro, @vlcheong .
The cause of your issue was a change made related to #1848 .
Previously, MyBatis used nested result mapping like <constructor /> to identify the parent object, however, the logic was complex and was not always valid, so we removed it from the mapping process.
It is unfortunate that the change broke your solution, but you basically need to add <id /> to the testResultMap with MyBatis ≥3.5.5.
<resultMap id="testResultMap" type="com.mapper.model.TestOrder">
<constructor>
<idArg resultMap="headerResultMap" javaType="com.mapper.model.TestHeader"/>
</constructor>
<id column="H_ID" /><!-- added -->
<collection property="details" ofType="com.mapper.model.TestDetail" resultMap="detailResultMap"/>
</resultMap>
@harawata Thanks for the solution. Will this solution works for composite key ?
It should. There can be multiple <id />s in a result map.
Issue solved after adding id tag