From 5ffd40cc84e1b1c3c6e3794ba1cd617522e1c326 Mon Sep 17 00:00:00 2001 From: Iwao AVE! Date: Mon, 10 Jul 2023 01:48:41 +0900 Subject: [PATCH] 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 --- .../resultset/DefaultResultSetHandler.java | 6 ++- .../submitted/discriminator/Contract.java | 36 ++++++++++++++ .../discriminator/DiscriminatorTest.java | 21 ++++++++ .../submitted/discriminator/Mapper.java | 4 ++ .../ibatis/submitted/discriminator/Owner.java | 12 ++++- .../submitted/discriminator/CreateDB.sql | 12 ++++- .../ibatis/submitted/discriminator/Mapper.xml | 48 ++++++++++++++++++- 7 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 src/test/java/org/apache/ibatis/submitted/discriminator/Contract.java diff --git a/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java b/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java index 38f913808c5..c1b67f1cec3 100644 --- a/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java +++ b/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java @@ -704,8 +704,10 @@ Object createParameterizedResultObject(ResultSetWrapper rsw, Class resultType if (constructorMapping.getNestedQueryId() != null) { value = getNestedQueryConstructorValue(rsw.getResultSet(), constructorMapping, columnPrefix); } else if (constructorMapping.getNestedResultMapId() != null) { - final ResultMap resultMap = configuration.getResultMap(constructorMapping.getNestedResultMapId()); - value = getRowValue(rsw, resultMap, getColumnPrefix(columnPrefix, constructorMapping)); + String constructorColumnPrefix = getColumnPrefix(columnPrefix, constructorMapping); + final ResultMap resultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), + configuration.getResultMap(constructorMapping.getNestedResultMapId()), constructorColumnPrefix); + value = getRowValue(rsw, resultMap, constructorColumnPrefix); } else { final TypeHandler typeHandler = constructorMapping.getTypeHandler(); value = typeHandler.getResult(rsw.getResultSet(), prependPrefix(column, columnPrefix)); diff --git a/src/test/java/org/apache/ibatis/submitted/discriminator/Contract.java b/src/test/java/org/apache/ibatis/submitted/discriminator/Contract.java new file mode 100644 index 00000000000..fbd09ee024b --- /dev/null +++ b/src/test/java/org/apache/ibatis/submitted/discriminator/Contract.java @@ -0,0 +1,36 @@ +/* + * Copyright 2009-2023 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.discriminator; + +public class Contract { + private Integer id; + private Owner owner; + + public Contract(Integer id, Owner owner) { + super(); + this.id = id; + this.owner = owner; + } + + public Integer getId() { + return id; + } + + public Owner getOwner() { + return owner; + } +} diff --git a/src/test/java/org/apache/ibatis/submitted/discriminator/DiscriminatorTest.java b/src/test/java/org/apache/ibatis/submitted/discriminator/DiscriminatorTest.java index d4a15254f9c..c406427c919 100644 --- a/src/test/java/org/apache/ibatis/submitted/discriminator/DiscriminatorTest.java +++ b/src/test/java/org/apache/ibatis/submitted/discriminator/DiscriminatorTest.java @@ -68,4 +68,25 @@ void shouldInheritResultType() { } } + @Test + void shouldBeAppliedToResultMapInConstructorArg() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + Mapper mapper = sqlSession.getMapper(Mapper.class); + List owners = mapper.selectOwnersWithAVehicleConstructor(); + assertEquals(Truck.class, owners.get(0).getVehicle().getClass()); + assertEquals(Car.class, owners.get(1).getVehicle().getClass()); + } + } + + @Test + void shouldBeAppliedToResultMapInConstructorArgNested() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + Mapper mapper = sqlSession.getMapper(Mapper.class); + List contracts = mapper.selectContracts(); + assertEquals(2, contracts.size()); + assertEquals(Truck.class, contracts.get(0).getOwner().getVehicle().getClass()); + assertEquals(Car.class, contracts.get(1).getOwner().getVehicle().getClass()); + } + } + } diff --git a/src/test/java/org/apache/ibatis/submitted/discriminator/Mapper.java b/src/test/java/org/apache/ibatis/submitted/discriminator/Mapper.java index 0b8ecd465d2..d21325dc725 100644 --- a/src/test/java/org/apache/ibatis/submitted/discriminator/Mapper.java +++ b/src/test/java/org/apache/ibatis/submitted/discriminator/Mapper.java @@ -23,4 +23,8 @@ public interface Mapper { List selectOwnersWithAVehicle(); + List selectOwnersWithAVehicleConstructor(); + + List selectContracts(); + } diff --git a/src/test/java/org/apache/ibatis/submitted/discriminator/Owner.java b/src/test/java/org/apache/ibatis/submitted/discriminator/Owner.java index 1d28c339549..b723137ff1e 100644 --- a/src/test/java/org/apache/ibatis/submitted/discriminator/Owner.java +++ b/src/test/java/org/apache/ibatis/submitted/discriminator/Owner.java @@ -1,5 +1,5 @@ /* - * Copyright 2009-2022 the original author or authors. + * Copyright 2009-2023 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. @@ -20,6 +20,16 @@ public class Owner { private String name; private Vehicle vehicle; + public Owner() { + super(); + } + + public Owner(Integer id, Vehicle vehicle) { + super(); + this.id = id; + this.vehicle = vehicle; + } + public Integer getId() { return id; } diff --git a/src/test/resources/org/apache/ibatis/submitted/discriminator/CreateDB.sql b/src/test/resources/org/apache/ibatis/submitted/discriminator/CreateDB.sql index 5943dd751ee..0c592942a54 100644 --- a/src/test/resources/org/apache/ibatis/submitted/discriminator/CreateDB.sql +++ b/src/test/resources/org/apache/ibatis/submitted/discriminator/CreateDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2009-2022 the original author or authors. +-- Copyright 2009-2023 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. @@ -16,6 +16,7 @@ drop table vehicle if exists; drop table owner if exists; +drop table contract if exists; create table vehicle ( id int, @@ -39,3 +40,12 @@ create table owner ( insert into owner (id, name, vehicle_type, vehicle_id) values (1, 'Owner1', 'truck', 2), (2, 'Owner2', 'car', 1); + +create table contract ( + id int, + owner_id int +); + +insert into contract (id, owner_id) values +(11, 1), +(12, 2); diff --git a/src/test/resources/org/apache/ibatis/submitted/discriminator/Mapper.xml b/src/test/resources/org/apache/ibatis/submitted/discriminator/Mapper.xml index 10235ec9a67..c8b0828f8c3 100644 --- a/src/test/resources/org/apache/ibatis/submitted/discriminator/Mapper.xml +++ b/src/test/resources/org/apache/ibatis/submitted/discriminator/Mapper.xml @@ -1,7 +1,7 @@