Skip to content

Commit 9548efb

Browse files
authored
Merge pull request #3391 from harawata/3108-follow-up-type-handler
`resultMap.hasResultMapsUsingConstructorCollection` should stay false if type handler is specified
2 parents 2de2506 + d1238a6 commit 9548efb

File tree

5 files changed

+123
-7
lines changed

5 files changed

+123
-7
lines changed

src/main/java/org/apache/ibatis/mapping/ResultMap.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2024 the original author or authors.
2+
* Copyright 2009-2025 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.
@@ -116,7 +116,7 @@ public ResultMap build() {
116116
// #101
117117
Class<?> javaType = resultMapping.getJavaType();
118118
resultMap.hasResultMapsUsingConstructorCollection = resultMap.hasResultMapsUsingConstructorCollection
119-
|| (resultMapping.getNestedQueryId() == null && javaType != null
119+
|| (resultMapping.getNestedQueryId() == null && resultMapping.getTypeHandler() == null && javaType != null
120120
&& resultMap.configuration.getObjectFactory().isCollection(javaType));
121121

122122
if (resultMapping.getProperty() != null) {

src/test/java/org/apache/ibatis/submitted/collection_in_constructor/CollectionInConstructorTest.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
package org.apache.ibatis.submitted.collection_in_constructor;
1717

18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.assertj.core.api.Assertions.tuple;
20+
1821
import java.io.Reader;
1922
import java.util.Arrays;
2023
import java.util.Collections;
@@ -164,6 +167,23 @@ void testCollectionArgWithTypeHandler() {
164167
}
165168
}
166169

170+
@Test
171+
void testCollectionArgWithNestedAndTypeHandler() {
172+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
173+
Mapper mapper = sqlSession.getMapper(Mapper.class);
174+
List<Store10> stores10 = mapper.getStores10();
175+
176+
assertThat(stores10).isNotNull().hasSize(3)
177+
.extracting(Store10::getId, Store10::getName, store -> store.getClerks().size(), Store10::getStrings)
178+
.containsExactly(tuple(1, "Store 1", 5, List.of("a", "b", "c", "1")),
179+
tuple(2, "Store 2", 0, List.of("a", "b", "c", "2")), tuple(3, "Store 3", 0, List.of("a", "b", "c", "3")));
180+
181+
assertThat(stores10.get(0).getClerks()).extracting(Clerk::getId, Clerk::getName).containsExactly(
182+
tuple(1001, "Clerk 1001"), tuple(1002, "Clerk 1002"), tuple(1003, "Clerk 1003"), tuple(1004, "Clerk 1004"),
183+
tuple(1005, "Clerk 1005"));
184+
}
185+
}
186+
167187
@Test
168188
void testImmutableNestedObjects() {
169189
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
@@ -203,17 +223,17 @@ void testImmutableNestedObjectsWithBadEquals() {
203223
new Store9(1, "Store 1", Arrays.asList(new Clerk(1002, "Clerk 1002"), new Clerk(1005, "Clerk 1005")))));
204224

205225
// cannot use direct equals as we overwrote it with a bad impl on purpose
206-
org.assertj.core.api.Assertions.assertThat(containers).isNotNull().hasSize(2);
226+
assertThat(containers).isNotNull().hasSize(2);
207227
assertContainer1(containers.get(0), expectedContainer1);
208228
assertContainer1(containers.get(1), expectedContainer2);
209229
}
210230
}
211231

212232
private static void assertContainer1(Container1 container1, Container1 expectedContainer1) {
213-
org.assertj.core.api.Assertions.assertThat(container1).isNotNull().satisfies(c -> {
214-
org.assertj.core.api.Assertions.assertThat(c.getNum()).isEqualTo(expectedContainer1.getNum());
215-
org.assertj.core.api.Assertions.assertThat(c.getType()).isEqualTo(expectedContainer1.getType());
216-
org.assertj.core.api.Assertions.assertThat(c.getStores()).isEqualTo(expectedContainer1.getStores());
233+
assertThat(container1).isNotNull().satisfies(c -> {
234+
assertThat(c.getNum()).isEqualTo(expectedContainer1.getNum());
235+
assertThat(c.getType()).isEqualTo(expectedContainer1.getType());
236+
assertThat(c.getStores()).isEqualTo(expectedContainer1.getStores());
217237
});
218238
}
219239
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ public interface Mapper {
4141

4242
List<Container1> getContainers();
4343

44+
List<Store10> getStores10();
4445
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2009-2024 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+
package org.apache.ibatis.submitted.collection_in_constructor;
17+
18+
import java.util.List;
19+
import java.util.Objects;
20+
21+
public class Store10 {
22+
23+
private final Integer id;
24+
private final String name;
25+
private final List<Clerk> clerks;
26+
private final List<String> strings;
27+
28+
public Store10(Integer id, String name, List<Clerk> clerks, List<String> strings) {
29+
this.id = id;
30+
this.name = name;
31+
this.clerks = clerks;
32+
this.strings = strings;
33+
}
34+
35+
public Integer getId() {
36+
return id;
37+
}
38+
39+
public String getName() {
40+
return name;
41+
}
42+
43+
public List<Clerk> getClerks() {
44+
return clerks;
45+
}
46+
47+
public List<String> getStrings() {
48+
return strings;
49+
}
50+
51+
@Override
52+
public boolean equals(Object o) {
53+
if (o == null || getClass() != o.getClass())
54+
return false;
55+
Store10 store10 = (Store10) o;
56+
return Objects.equals(id, store10.id) && Objects.equals(name, store10.name)
57+
&& Objects.equals(clerks, store10.clerks) && Objects.equals(strings, store10.strings);
58+
}
59+
60+
@Override
61+
public int hashCode() {
62+
return Objects.hash(id, name, clerks, strings);
63+
}
64+
65+
@Override
66+
public String toString() {
67+
return "Store10{" + "id=" + id + ", name='" + name + '\'' + ", clerks=" + clerks + ", strings=" + strings + '}';
68+
}
69+
}

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,4 +277,30 @@
277277
order by type, s.id, c.id
278278
]]></select>
279279

280+
<resultMap
281+
type="org.apache.ibatis.submitted.collection_in_constructor.Store10"
282+
id="store10RM">
283+
<constructor>
284+
<idArg column="id" javaType="int" />
285+
<arg column="name" javaType="string" />
286+
<arg javaType="list" resultMap="immutableClerkRM" columnPrefix="clerk_" />
287+
<arg column="csv" javaType="list"
288+
typeHandler="org.apache.ibatis.submitted.collection_in_constructor.CsvToListTypeHandler" />
289+
</constructor>
290+
</resultMap>
291+
292+
<select id="getStores10" resultMap="store10RM"
293+
resultOrdered="true"><![CDATA[
294+
select
295+
s.id,
296+
s.name,
297+
c.id clerk_id, c.name clerk_name,
298+
i.id aisle_id, i.name aisle_name,
299+
CONCAT('a,b,c,', s.id) csv
300+
from store s
301+
left join clerk c on c.store_id = s.id
302+
left join aisle i on i.store_id = s.id
303+
order by s.id, c.id, i.id
304+
]]></select>
305+
280306
</mapper>

0 commit comments

Comments
 (0)