diff --git a/src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java b/src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java index 8b853d096fb..e272f8b1d8c 100644 --- a/src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java +++ b/src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java @@ -437,7 +437,7 @@ private Class resolveResultJavaType(Class resultType, String property, Cla if (javaType == null && property != null) { try { MetaClass metaResultType = MetaClass.forClass(resultType, configuration.getReflectorFactory()); - javaType = metaResultType.getGetterType(property); + javaType = metaResultType.getSetterType(property); } catch (Exception e) { // ignore, following null check statement will deal with the situation } diff --git a/src/main/java/org/apache/ibatis/mapping/ResultMap.java b/src/main/java/org/apache/ibatis/mapping/ResultMap.java index 5115dcd9c28..a4f7d4ae57a 100644 --- a/src/main/java/org/apache/ibatis/mapping/ResultMap.java +++ b/src/main/java/org/apache/ibatis/mapping/ResultMap.java @@ -129,7 +129,7 @@ public ResultMap build() { if (actualArgNames == null) { throw new BuilderException("Error in result map '" + resultMap.id + "'. Failed to find a constructor in '" + resultMap.getType().getName() + "' with arg names " + constructorArgNames - + ". Note that 'javaType' is required when there is no readable property with the same name ('name' is optional, BTW). There might be more info in debug log."); + + ". Note that 'javaType' is required when there is no writable property with the same name ('name' is optional, BTW). There might be more info in debug log."); } resultMap.constructorResultMappings.sort((o1, o2) -> { int paramIdx1 = actualArgNames.indexOf(o1.getProperty()); diff --git a/src/site/es/xdoc/sqlmap-xml.xml b/src/site/es/xdoc/sqlmap-xml.xml index 48b530de187..166f7da059a 100644 --- a/src/site/es/xdoc/sqlmap-xml.xml +++ b/src/site/es/xdoc/sqlmap-xml.xml @@ -986,7 +986,7 @@ public class User { ]]>

- javaType can be omitted if there is a property with the same name and type. + javaType can be omitted if there is a writable property with the same name and type.

El resto de atributos son los mismos que los de los elementos id y result.

diff --git a/src/site/ja/xdoc/sqlmap-xml.xml b/src/site/ja/xdoc/sqlmap-xml.xml index eae6ca58207..6e4901b9724 100644 --- a/src/site/ja/xdoc/sqlmap-xml.xml +++ b/src/site/ja/xdoc/sqlmap-xml.xml @@ -1102,7 +1102,7 @@ public class User { ]]>

- 引数と同じ名前、同じ型を持つプロパティが存在する場合 javaType は省略可能です。 + 引数と同じ名前、同じ型を持つ書き込み可能なプロパティが存在する場合 javaType は省略可能です。

diff --git a/src/site/ko/xdoc/sqlmap-xml.xml b/src/site/ko/xdoc/sqlmap-xml.xml index 33965b3c2fa..e5c5dd01d64 100644 --- a/src/site/ko/xdoc/sqlmap-xml.xml +++ b/src/site/ko/xdoc/sqlmap-xml.xml @@ -986,7 +986,7 @@ public class User { ]]>

- 같은 이름과 형태의 property 가 있는 경우는 javaType 를 생략 할 수 있다. + 같은 이름과 형태의 쓰기 가능한 property 가 있는 경우는 javaType 를 생략 할 수 있다.

나머지 속성과 규칙은 id와 result엘리먼트와 동일하다.

diff --git a/src/site/xdoc/sqlmap-xml.xml b/src/site/xdoc/sqlmap-xml.xml index 21332e04a5a..fb5f98848f4 100644 --- a/src/site/xdoc/sqlmap-xml.xml +++ b/src/site/xdoc/sqlmap-xml.xml @@ -1190,7 +1190,7 @@ public class User { ]]>

- javaType can be omitted if there is a property with the same name and type. + javaType can be omitted if there is a writable property with the same name and type.

diff --git a/src/site/zh/xdoc/sqlmap-xml.xml b/src/site/zh/xdoc/sqlmap-xml.xml index 7e5709fc3ee..705f457b611 100644 --- a/src/site/zh/xdoc/sqlmap-xml.xml +++ b/src/site/zh/xdoc/sqlmap-xml.xml @@ -1135,7 +1135,7 @@ public class User { ]]>

- 如果存在名称和类型相同的属性,那么可以省略 javaType 。 + 如果存在名称和类型相同的可写属性,那么可以省略 javaType

diff --git a/src/test/java/org/apache/ibatis/submitted/record_type/RecordTypeMapper.java b/src/test/java/org/apache/ibatis/submitted/record_type/RecordTypeMapper.java index 6101fa35206..ccc0e479055 100644 --- a/src/test/java/org/apache/ibatis/submitted/record_type/RecordTypeMapper.java +++ b/src/test/java/org/apache/ibatis/submitted/record_type/RecordTypeMapper.java @@ -32,12 +32,6 @@ public interface RecordTypeMapper { @Select("select val, id, url from prop where id = #{id}") Property selectProperty(int id); - @Arg(name = "id", column = "id", id = true) - @Arg(name = "value", column = "val") - @Arg(name = "URL", column = "url") - @Select("select val, id, url from prop where id = #{id}") - Property selectPropertyNoJavaType(int id); - @Insert("insert into prop (id, val, url) values (#{id}, #{value}, #{URL})") int insertProperty(Property property); diff --git a/src/test/java/org/apache/ibatis/submitted/record_type/RecordTypeTest.java b/src/test/java/org/apache/ibatis/submitted/record_type/RecordTypeTest.java index af368b47e13..de4c6ea98ca 100644 --- a/src/test/java/org/apache/ibatis/submitted/record_type/RecordTypeTest.java +++ b/src/test/java/org/apache/ibatis/submitted/record_type/RecordTypeTest.java @@ -52,16 +52,6 @@ void testSelectRecord() { } } - @Test - void shouldResolveConstructorArgType() { - try (SqlSession sqlSession = sqlSessionFactory.openSession()) { - RecordTypeMapper mapper = sqlSession.getMapper(RecordTypeMapper.class); - Property prop = mapper.selectPropertyNoJavaType(1); - assertEquals("Val1!", prop.value()); - assertEquals("https://www.google.com", prop.URL()); - } - } - @Test void testSelectRecordAutomapping() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { diff --git a/src/test/java/org/apache/ibatis/submitted/unmatched_prop_type/UnmatchedPropTypeMapper.java b/src/test/java/org/apache/ibatis/submitted/unmatched_prop_type/UnmatchedPropTypeMapper.java new file mode 100644 index 00000000000..c677f703eee --- /dev/null +++ b/src/test/java/org/apache/ibatis/submitted/unmatched_prop_type/UnmatchedPropTypeMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright 2009-2022 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.unmatched_prop_type; + +import org.apache.ibatis.annotations.Arg; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Select; + +public interface UnmatchedPropTypeMapper { + + // javaType is required for 'id' + @Arg(id = true, column = "id", name = "id", javaType = String.class) + @Arg(column = "name", name = "name") + @Result(column = "dob", property = "dob") + @Select("select * from users where id = #{id}") + User getUser(Integer id); + +} diff --git a/src/test/java/org/apache/ibatis/submitted/unmatched_prop_type/UnmatchedPropTypeTest.java b/src/test/java/org/apache/ibatis/submitted/unmatched_prop_type/UnmatchedPropTypeTest.java new file mode 100644 index 00000000000..abe38ec4b4b --- /dev/null +++ b/src/test/java/org/apache/ibatis/submitted/unmatched_prop_type/UnmatchedPropTypeTest.java @@ -0,0 +1,51 @@ +/* + * 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.unmatched_prop_type; + +import java.io.Reader; + +import org.apache.ibatis.BaseDataTest; +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class UnmatchedPropTypeTest { + + private static SqlSessionFactory sqlSessionFactory; + + @BeforeAll + static void setUp() throws Exception { + try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/unmatched_prop_type/mybatis-config.xml")) { + sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); + } + BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), + "org/apache/ibatis/submitted/unmatched_prop_type/CreateDB.sql"); + } + + @Test + void shouldGetAUser() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + UnmatchedPropTypeMapper mapper = sqlSession.getMapper(UnmatchedPropTypeMapper.class); + User user = mapper.getUser(1); + Assertions.assertEquals("User1", user.getName()); + } + } + +} diff --git a/src/test/java/org/apache/ibatis/submitted/unmatched_prop_type/User.java b/src/test/java/org/apache/ibatis/submitted/unmatched_prop_type/User.java new file mode 100644 index 00000000000..66e604b2750 --- /dev/null +++ b/src/test/java/org/apache/ibatis/submitted/unmatched_prop_type/User.java @@ -0,0 +1,59 @@ +/* + * Copyright 2009-2022 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.unmatched_prop_type; + +import java.time.LocalDate; + +public class User { + private final Integer id; + private final String name; + private Birthday dob; + + public User(String id, String name) { + super(); + this.id = Integer.valueOf(id); + this.name = name; + } + + public Integer getId() { + return id; + } + + public String getName() { + return name; + } + + public Birthday getDob() { + return dob; + } + + public void setDob(String dob) { + this.dob = new Birthday(dob); + } + + class Birthday { + private final LocalDate date; + + Birthday(String date) { + this.date = LocalDate.parse(date); + } + + public LocalDate getDate() { + return date; + } + + } +} diff --git a/src/test/resources/org/apache/ibatis/submitted/unmatched_prop_type/CreateDB.sql b/src/test/resources/org/apache/ibatis/submitted/unmatched_prop_type/CreateDB.sql new file mode 100644 index 00000000000..cdbffeb2ca7 --- /dev/null +++ b/src/test/resources/org/apache/ibatis/submitted/unmatched_prop_type/CreateDB.sql @@ -0,0 +1,26 @@ +-- +-- Copyright 2009-2022 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. +-- + +drop table users if exists; + +create table users ( + id int, + name varchar(20), + dob varchar(10) +); + +insert into users (id, name, dob) +values (1, 'User1', '2000-01-01'); diff --git a/src/test/resources/org/apache/ibatis/submitted/unmatched_prop_type/mybatis-config.xml b/src/test/resources/org/apache/ibatis/submitted/unmatched_prop_type/mybatis-config.xml new file mode 100644 index 00000000000..af73f60e2af --- /dev/null +++ b/src/test/resources/org/apache/ibatis/submitted/unmatched_prop_type/mybatis-config.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + +