Skip to content

Commit 5ffd40c

Browse files
committed
Support result map with discriminator in constructor mapping
Currently, discriminator is not correctly evaluated in a result map that is referenced from a constructor mapping. Reported in https://stackoverflow.com/q/76177553/1261766
1 parent 286b302 commit 5ffd40c

File tree

7 files changed

+134
-5
lines changed

7 files changed

+134
-5
lines changed

src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,10 @@ Object createParameterizedResultObject(ResultSetWrapper rsw, Class<?> resultType
704704
if (constructorMapping.getNestedQueryId() != null) {
705705
value = getNestedQueryConstructorValue(rsw.getResultSet(), constructorMapping, columnPrefix);
706706
} else if (constructorMapping.getNestedResultMapId() != null) {
707-
final ResultMap resultMap = configuration.getResultMap(constructorMapping.getNestedResultMapId());
708-
value = getRowValue(rsw, resultMap, getColumnPrefix(columnPrefix, constructorMapping));
707+
String constructorColumnPrefix = getColumnPrefix(columnPrefix, constructorMapping);
708+
final ResultMap resultMap = resolveDiscriminatedResultMap(rsw.getResultSet(),
709+
configuration.getResultMap(constructorMapping.getNestedResultMapId()), constructorColumnPrefix);
710+
value = getRowValue(rsw, resultMap, constructorColumnPrefix);
709711
} else {
710712
final TypeHandler<?> typeHandler = constructorMapping.getTypeHandler();
711713
value = typeHandler.getResult(rsw.getResultSet(), prependPrefix(column, columnPrefix));
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2009-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.apache.ibatis.submitted.discriminator;
18+
19+
public class Contract {
20+
private Integer id;
21+
private Owner owner;
22+
23+
public Contract(Integer id, Owner owner) {
24+
super();
25+
this.id = id;
26+
this.owner = owner;
27+
}
28+
29+
public Integer getId() {
30+
return id;
31+
}
32+
33+
public Owner getOwner() {
34+
return owner;
35+
}
36+
}

src/test/java/org/apache/ibatis/submitted/discriminator/DiscriminatorTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,25 @@ void shouldInheritResultType() {
6868
}
6969
}
7070

71+
@Test
72+
void shouldBeAppliedToResultMapInConstructorArg() {
73+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
74+
Mapper mapper = sqlSession.getMapper(Mapper.class);
75+
List<Owner> owners = mapper.selectOwnersWithAVehicleConstructor();
76+
assertEquals(Truck.class, owners.get(0).getVehicle().getClass());
77+
assertEquals(Car.class, owners.get(1).getVehicle().getClass());
78+
}
79+
}
80+
81+
@Test
82+
void shouldBeAppliedToResultMapInConstructorArgNested() {
83+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
84+
Mapper mapper = sqlSession.getMapper(Mapper.class);
85+
List<Contract> contracts = mapper.selectContracts();
86+
assertEquals(2, contracts.size());
87+
assertEquals(Truck.class, contracts.get(0).getOwner().getVehicle().getClass());
88+
assertEquals(Car.class, contracts.get(1).getOwner().getVehicle().getClass());
89+
}
90+
}
91+
7192
}

src/test/java/org/apache/ibatis/submitted/discriminator/Mapper.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@ public interface Mapper {
2323

2424
List<Owner> selectOwnersWithAVehicle();
2525

26+
List<Owner> selectOwnersWithAVehicleConstructor();
27+
28+
List<Contract> selectContracts();
29+
2630
}

src/test/java/org/apache/ibatis/submitted/discriminator/Owner.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2022 the original author or authors.
2+
* Copyright 2009-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,16 @@ public class Owner {
2020
private String name;
2121
private Vehicle vehicle;
2222

23+
public Owner() {
24+
super();
25+
}
26+
27+
public Owner(Integer id, Vehicle vehicle) {
28+
super();
29+
this.id = id;
30+
this.vehicle = vehicle;
31+
}
32+
2333
public Integer getId() {
2434
return id;
2535
}

src/test/resources/org/apache/ibatis/submitted/discriminator/CreateDB.sql

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--
2-
-- Copyright 2009-2022 the original author or authors.
2+
-- Copyright 2009-2023 the original author or authors.
33
--
44
-- Licensed under the Apache License, Version 2.0 (the "License");
55
-- you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616

1717
drop table vehicle if exists;
1818
drop table owner if exists;
19+
drop table contract if exists;
1920

2021
create table vehicle (
2122
id int,
@@ -39,3 +40,12 @@ create table owner (
3940
insert into owner (id, name, vehicle_type, vehicle_id) values
4041
(1, 'Owner1', 'truck', 2),
4142
(2, 'Owner2', 'car', 1);
43+
44+
create table contract (
45+
id int,
46+
owner_id int
47+
);
48+
49+
insert into contract (id, owner_id) values
50+
(11, 1),
51+
(12, 2);

src/test/resources/org/apache/ibatis/submitted/discriminator/Mapper.xml

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
4-
Copyright 2009-2022 the original author or authors.
4+
Copyright 2009-2023 the original author or authors.
55
66
Licensed under the Apache License, Version 2.0 (the "License");
77
you may not use this file except in compliance with the License.
@@ -81,4 +81,50 @@
8181
where id = #{id}
8282
]]></select>
8383

84+
<resultMap
85+
type="org.apache.ibatis.submitted.discriminator.Owner"
86+
id="ownerConstructorResult">
87+
<constructor>
88+
<idArg javaType="int" column="id" />
89+
<arg javaType="org.apache.ibatis.submitted.discriminator.Vehicle"
90+
resultMap="vehicleResult" columnPrefix="vhc_" />
91+
</constructor>
92+
<result javaType="string" column="name" />
93+
</resultMap>
94+
95+
<select id="selectOwnersWithAVehicleConstructor"
96+
resultMap="ownerConstructorResult"><![CDATA[
97+
select onr.id, onr.name,
98+
vhc.id vhc_id,
99+
vhc.maker vhc_maker,
100+
vhc.vehicle_type vhc_vehicle_type,
101+
vhc.door_count vhc_door_count,
102+
vhc.carrying_capacity vhc_carrying_capacity
103+
from owner onr
104+
left join vehicle vhc on vhc.id = onr.vehicle_id
105+
]]></select>
106+
107+
<resultMap
108+
type="org.apache.ibatis.submitted.discriminator.Contract"
109+
id="contractResult">
110+
<constructor>
111+
<idArg javaType="int" column="id" />
112+
<arg javaType="org.apache.ibatis.submitted.discriminator.Owner"
113+
resultMap="ownerConstructorResult" columnPrefix="onr_" />
114+
</constructor>
115+
</resultMap>
116+
117+
<select id="selectContracts" resultMap="contractResult"><![CDATA[
118+
select ctt.id,
119+
onr.id onr_id, onr.name onr_name,
120+
vhc.id onr_vhc_id,
121+
vhc.maker onr_vhc_maker,
122+
vhc.vehicle_type onr_vhc_vehicle_type,
123+
vhc.door_count onr_vhc_door_count,
124+
vhc.carrying_capacity onr_vhc_carrying_capacity
125+
from contract ctt
126+
left join owner onr on onr.id = ctt.owner_id
127+
left join vehicle vhc on vhc.id = onr.vehicle_id
128+
]]></select>
129+
84130
</mapper>

0 commit comments

Comments
 (0)