Skip to content

Commit 4ed48b1

Browse files
committed
Jdbc3KeyGenerator should use Type instead of Class in handler resolution
1 parent 1261a34 commit 4ed48b1

File tree

7 files changed

+123
-3
lines changed

7 files changed

+123
-3
lines changed

src/main/java/org/apache/ibatis/executor/keygen/Jdbc3KeyGenerator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.apache.ibatis.executor.keygen;
1717

18+
import java.lang.reflect.Type;
1819
import java.sql.ResultSet;
1920
import java.sql.ResultSetMetaData;
2021
import java.sql.SQLException;
@@ -259,7 +260,7 @@ protected void assign(ResultSet rs, Object param) {
259260
throw new ExecutorException("No setter found for the keyProperty '" + propertyName + "' in '"
260261
+ metaParam.getOriginalObject().getClass().getName() + "'.");
261262
}
262-
Class<?> propertyType = metaParam.getSetterType(propertyName);
263+
Type propertyType = metaParam.getGenericSetterType(propertyName).getKey();
263264
JdbcType jdbcType = JdbcType.forCode(rsmd.getColumnType(columnPosition));
264265
typeHandler = typeHandlerRegistry.getTypeHandler(propertyType, jdbcType);
265266
if (typeHandler == null) {

src/test/java/org/apache/ibatis/submitted/typebasedtypehandlerresolution/GloballyRegisteredHandlerMapper.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515
*/
1616
package org.apache.ibatis.submitted.typebasedtypehandlerresolution;
1717

18+
import java.util.List;
19+
1820
import org.apache.ibatis.annotations.Insert;
21+
import org.apache.ibatis.annotations.Options;
22+
import org.apache.ibatis.annotations.Param;
1923
import org.apache.ibatis.annotations.Result;
2024
import org.apache.ibatis.annotations.Select;
2125

@@ -49,4 +53,12 @@ public interface GloballyRegisteredHandlerMapper {
4953
ParentBean selectNestedUser_SingleParam(Integer id);
5054

5155
ParentBean selectNestedUser_MultiParam(Integer id);
56+
57+
@Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id")
58+
@Insert("insert into product (name) values (#{name})")
59+
int insertProduct(Product product);
60+
61+
int insertProducts(List<Product> products);
62+
63+
int insertProducts2(@Param("dummy") String dummy, @Param("products") List<Product> products);
5264
}

src/test/java/org/apache/ibatis/submitted/typebasedtypehandlerresolution/GloballyRegisteredTypeHandlerResolutionTest.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.apache.ibatis.submitted.typebasedtypehandlerresolution;
1717

1818
import static org.junit.jupiter.api.Assertions.assertEquals;
19+
import static org.junit.jupiter.api.Assertions.assertNotNull;
1920

2021
import java.util.Arrays;
2122
import java.util.List;
@@ -219,4 +220,43 @@ void shouldHandlerAppliedToNestedSelectMultiParam() {
219220
assertEquals(1, bean.getUser().getId());
220221
}
221222
}
223+
224+
@Test
225+
void shouldHandlerGeneratedKey() {
226+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
227+
GloballyRegisteredHandlerMapper mapper = sqlSession.getMapper(GloballyRegisteredHandlerMapper.class);
228+
Product product = new Product();
229+
product.setName("Great product");
230+
assertEquals(1, mapper.insertProduct(product));
231+
assertNotNull(product.getId());
232+
}
233+
}
234+
235+
@Test
236+
void shouldHandlerGeneratedKeys() {
237+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
238+
GloballyRegisteredHandlerMapper mapper = sqlSession.getMapper(GloballyRegisteredHandlerMapper.class);
239+
Product product1 = new Product();
240+
product1.setName("Great product");
241+
Product product2 = new Product();
242+
product2.setName("Good product");
243+
assertEquals(2, mapper.insertProducts(List.of(product1, product2)));
244+
assertNotNull(product1.getId());
245+
assertNotNull(product2.getId());
246+
}
247+
}
248+
249+
@Test
250+
void shouldHandlerGeneratedKeys_MultiParams() {
251+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
252+
GloballyRegisteredHandlerMapper mapper = sqlSession.getMapper(GloballyRegisteredHandlerMapper.class);
253+
Product product1 = new Product();
254+
product1.setName("Great product");
255+
Product product2 = new Product();
256+
product2.setName("Good product");
257+
assertEquals(2, mapper.insertProducts2("dummy", List.of(product1, product2)));
258+
assertNotNull(product1.getId());
259+
assertNotNull(product2.getId());
260+
}
261+
}
222262
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2009-2025 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.typebasedtypehandlerresolution;
18+
19+
public class Product {
20+
private FuzzyBean<Integer> id;
21+
private String name;
22+
23+
public FuzzyBean<Integer> getId() {
24+
return id;
25+
}
26+
27+
public void setId(FuzzyBean<Integer> id) {
28+
this.id = id;
29+
}
30+
31+
public String getName() {
32+
return name;
33+
}
34+
35+
public void setName(String name) {
36+
this.name = name;
37+
}
38+
}

src/test/java/org/apache/ibatis/submitted/typebasedtypehandlerresolution/TypeAwareTypeHandler.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-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.
@@ -79,6 +79,16 @@ public Object getResult(ResultSet rs, String columnName) throws SQLException {
7979

8080
@Override
8181
public Object getResult(ResultSet rs, int columnIndex) throws SQLException {
82+
if (FuzzyBean.class.equals(rawType)) {
83+
if (String.class.equals(typeArg)) {
84+
return new FuzzyBean<String>(rs.getString(columnIndex));
85+
} else if (Integer.class.equals(typeArg)) {
86+
return new FuzzyBean<Integer>(rs.getInt(columnIndex));
87+
}
88+
} else if (LocalDate.class.equals(rawType)) {
89+
int v = rs.getInt(columnIndex);
90+
return v == 0 ? null : LocalDate.of(v / 10000, v / 100 % 100, v % 100);
91+
}
8292
return null;
8393
}
8494

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

Lines changed: 7 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-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.
@@ -30,3 +30,9 @@ insert into users (id, strvalue, intvalue, datevalue, datevalue2, strings, integ
3030
values(1, 'garden', 31, 20200511, '2020-05-09', 'a,b,c', '1,3,5');
3131
insert into users (id, strvalue, intvalue, datevalue, datevalue2, strings, integers)
3232
values(2, 'vault', 32, 20200512, '2020-05-10', 'd,e,f', '7,9');
33+
34+
35+
create table product (
36+
id int identity,
37+
name varchar(20)
38+
);

src/test/resources/org/apache/ibatis/submitted/typebasedtypehandlerresolution/GloballyRegisteredHandlerMapper.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,17 @@
7676
where strvalue = #{strvalue} and intvalue = #{intvalue}
7777
</select>
7878

79+
<insert id="insertProducts" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
80+
insert into product (name) values
81+
<foreach collection="list" item="product" separator=",">
82+
(#{product.name})
83+
</foreach>
84+
</insert>
85+
86+
<insert id="insertProducts2" useGeneratedKeys="true" keyColumn="id" keyProperty="products.id">
87+
insert into product (name) values
88+
<foreach collection="products" item="product" separator=",">
89+
(#{product.name})
90+
</foreach>
91+
</insert>
7992
</mapper>

0 commit comments

Comments
 (0)