From 14f0f5d285fd9bfa09615f258afcc29847757d19 Mon Sep 17 00:00:00 2001 From: Iwao AVE! Date: Tue, 7 Jan 2025 04:40:44 +0900 Subject: [PATCH 1/3] `resultMap.hasResultMapsUsingConstructorCollection` should stay false if type handler is specified --- src/main/java/org/apache/ibatis/mapping/ResultMap.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/ibatis/mapping/ResultMap.java b/src/main/java/org/apache/ibatis/mapping/ResultMap.java index 58ce5dd6f6a..a7c8ebe494a 100644 --- a/src/main/java/org/apache/ibatis/mapping/ResultMap.java +++ b/src/main/java/org/apache/ibatis/mapping/ResultMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2009-2024 the original author or authors. + * Copyright 2009-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -116,7 +116,7 @@ public ResultMap build() { // #101 Class javaType = resultMapping.getJavaType(); resultMap.hasResultMapsUsingConstructorCollection = resultMap.hasResultMapsUsingConstructorCollection - || (resultMapping.getNestedQueryId() == null && javaType != null + || (resultMapping.getNestedQueryId() == null && resultMapping.getTypeHandler() == null && javaType != null && resultMap.configuration.getObjectFactory().isCollection(javaType)); if (resultMapping.getProperty() != null) { From 640b93015659287955ec4cfdfa70bfafc2b025a8 Mon Sep 17 00:00:00 2001 From: Willie Scholtz Date: Tue, 7 Jan 2025 10:47:41 +0100 Subject: [PATCH 2/3] Add additional test with mix of nested result map and type handler --- .../CollectionInConstructorTest.java | 30 ++++++-- .../collection_in_constructor/Mapper.java | 1 + .../collection_in_constructor/Store10.java | 69 +++++++++++++++++++ .../collection_in_constructor/Mapper.xml | 26 +++++++ 4 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 src/test/java/org/apache/ibatis/submitted/collection_in_constructor/Store10.java diff --git a/src/test/java/org/apache/ibatis/submitted/collection_in_constructor/CollectionInConstructorTest.java b/src/test/java/org/apache/ibatis/submitted/collection_in_constructor/CollectionInConstructorTest.java index 20aa7db18b2..6267f9af13c 100644 --- a/src/test/java/org/apache/ibatis/submitted/collection_in_constructor/CollectionInConstructorTest.java +++ b/src/test/java/org/apache/ibatis/submitted/collection_in_constructor/CollectionInConstructorTest.java @@ -15,6 +15,9 @@ */ package org.apache.ibatis.submitted.collection_in_constructor; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + import java.io.Reader; import java.util.Arrays; import java.util.Collections; @@ -164,6 +167,23 @@ void testCollectionArgWithTypeHandler() { } } + @Test + void testCollectionArgWithNestedAndTypeHandler() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + Mapper mapper = sqlSession.getMapper(Mapper.class); + List stores10 = mapper.getStores10(); + + assertThat(stores10).isNotNull().hasSize(3) + .extracting(Store10::getId, Store10::getName, store -> store.getClerks().size(), Store10::getStrings) + .containsExactly(tuple(1, "Store 1", 5, List.of("a", "b", "c", "1")), + tuple(2, "Store 2", 0, List.of("a", "b", "c", "2")), tuple(3, "Store 3", 0, List.of("a", "b", "c", "3"))); + + assertThat(stores10.get(0).getClerks()).extracting(Clerk::getId, Clerk::getName).containsExactly( + tuple(1001, "Clerk 1001"), tuple(1002, "Clerk 1002"), tuple(1003, "Clerk 1003"), tuple(1004, "Clerk 1004"), + tuple(1005, "Clerk 1005")); + } + } + @Test void testImmutableNestedObjects() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { @@ -203,17 +223,17 @@ void testImmutableNestedObjectsWithBadEquals() { new Store9(1, "Store 1", Arrays.asList(new Clerk(1002, "Clerk 1002"), new Clerk(1005, "Clerk 1005"))))); // cannot use direct equals as we overwrote it with a bad impl on purpose - org.assertj.core.api.Assertions.assertThat(containers).isNotNull().hasSize(2); + assertThat(containers).isNotNull().hasSize(2); assertContainer1(containers.get(0), expectedContainer1); assertContainer1(containers.get(1), expectedContainer2); } } private static void assertContainer1(Container1 container1, Container1 expectedContainer1) { - org.assertj.core.api.Assertions.assertThat(container1).isNotNull().satisfies(c -> { - org.assertj.core.api.Assertions.assertThat(c.getNum()).isEqualTo(expectedContainer1.getNum()); - org.assertj.core.api.Assertions.assertThat(c.getType()).isEqualTo(expectedContainer1.getType()); - org.assertj.core.api.Assertions.assertThat(c.getStores()).isEqualTo(expectedContainer1.getStores()); + assertThat(container1).isNotNull().satisfies(c -> { + assertThat(c.getNum()).isEqualTo(expectedContainer1.getNum()); + assertThat(c.getType()).isEqualTo(expectedContainer1.getType()); + assertThat(c.getStores()).isEqualTo(expectedContainer1.getStores()); }); } } diff --git a/src/test/java/org/apache/ibatis/submitted/collection_in_constructor/Mapper.java b/src/test/java/org/apache/ibatis/submitted/collection_in_constructor/Mapper.java index 0aa4db76a2e..79e36371c4a 100644 --- a/src/test/java/org/apache/ibatis/submitted/collection_in_constructor/Mapper.java +++ b/src/test/java/org/apache/ibatis/submitted/collection_in_constructor/Mapper.java @@ -41,4 +41,5 @@ public interface Mapper { List getContainers(); + List getStores10(); } diff --git a/src/test/java/org/apache/ibatis/submitted/collection_in_constructor/Store10.java b/src/test/java/org/apache/ibatis/submitted/collection_in_constructor/Store10.java new file mode 100644 index 00000000000..48041dd8ed6 --- /dev/null +++ b/src/test/java/org/apache/ibatis/submitted/collection_in_constructor/Store10.java @@ -0,0 +1,69 @@ +/* + * Copyright 2009-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ibatis.submitted.collection_in_constructor; + +import java.util.List; +import java.util.Objects; + +public class Store10 { + + private final Integer id; + private final String name; + private final List clerks; + private final List strings; + + public Store10(Integer id, String name, List clerks, List strings) { + this.id = id; + this.name = name; + this.clerks = clerks; + this.strings = strings; + } + + public Integer getId() { + return id; + } + + public String getName() { + return name; + } + + public List getClerks() { + return clerks; + } + + public List getStrings() { + return strings; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) + return false; + Store10 store10 = (Store10) o; + return Objects.equals(id, store10.id) && Objects.equals(name, store10.name) + && Objects.equals(clerks, store10.clerks) && Objects.equals(strings, store10.strings); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, clerks, strings); + } + + @Override + public String toString() { + return "Store10{" + "id=" + id + ", name='" + name + '\'' + ", clerks=" + clerks + ", strings=" + strings + '}'; + } +} diff --git a/src/test/resources/org/apache/ibatis/submitted/collection_in_constructor/Mapper.xml b/src/test/resources/org/apache/ibatis/submitted/collection_in_constructor/Mapper.xml index 47aa2887c88..9ee9697c80d 100644 --- a/src/test/resources/org/apache/ibatis/submitted/collection_in_constructor/Mapper.xml +++ b/src/test/resources/org/apache/ibatis/submitted/collection_in_constructor/Mapper.xml @@ -277,4 +277,30 @@ order by type, s.id, c.id ]]> + + + + + + + + + + + From b13e7d8f7ea134dbc877dee8a540d6ba16af2d6a Mon Sep 17 00:00:00 2001 From: Iwao AVE! Date: Thu, 9 Jan 2025 07:19:44 +0900 Subject: [PATCH 3/3] Specify the default tag for PostgreSQL container After the recent change 7a4167d9f6148f88e3de6f1c5f329a70ebfff30f , NetworkTimeoutTest fails consistently on my environment (Apple M3 MAX w/ Colima). Assuming it is a temporary issue, I didn't look into it. --- .../java/org/apache/ibatis/testcontainers/PgContainer.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/apache/ibatis/testcontainers/PgContainer.java b/src/test/java/org/apache/ibatis/testcontainers/PgContainer.java index b33e3c8fb8c..29cf3391473 100644 --- a/src/test/java/org/apache/ibatis/testcontainers/PgContainer.java +++ b/src/test/java/org/apache/ibatis/testcontainers/PgContainer.java @@ -19,6 +19,7 @@ import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.utility.DockerImageName; public final class PgContainer { @@ -31,8 +32,9 @@ public final class PgContainer { private static PostgreSQLContainer initContainer() { @SuppressWarnings("resource") - PostgreSQLContainer container = new PostgreSQLContainer<>("postgres").withDatabaseName(DB_NAME) - .withUsername(USERNAME).withPassword(PASSWORD); + PostgreSQLContainer container = new PostgreSQLContainer<>( + DockerImageName.parse("postgres").withTag(PostgreSQLContainer.DEFAULT_TAG)).withDatabaseName(DB_NAME) + .withUsername(USERNAME).withPassword(PASSWORD); container.start(); return container; }