Skip to content

Commit 90103b0

Browse files
committed
Consistent support for direct column matches in DataClassRowMapper
Closes gh-28243
1 parent 0cf15c0 commit 90103b0

File tree

8 files changed

+69
-35
lines changed

8 files changed

+69
-35
lines changed

spring-jdbc/src/main/java/org/springframework/jdbc/core/DataClassRowMapper.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -98,9 +98,18 @@ protected T constructMappedInstance(ResultSet rs, TypeConverter tc) throws SQLEx
9898
if (this.constructorParameterNames != null && this.constructorParameterTypes != null) {
9999
args = new Object[this.constructorParameterNames.length];
100100
for (int i = 0; i < args.length; i++) {
101-
String name = underscoreName(this.constructorParameterNames[i]);
101+
String name = this.constructorParameterNames[i];
102+
int index;
103+
try {
104+
// Try direct name match first
105+
index = rs.findColumn(lowerCaseName(name));
106+
}
107+
catch (SQLException ex) {
108+
// Try underscored name match instead
109+
index = rs.findColumn(underscoreName(name));
110+
}
102111
TypeDescriptor td = this.constructorParameterTypes[i];
103-
Object value = getColumnValue(rs, rs.findColumn(name), td.getType());
112+
Object value = getColumnValue(rs, index, td.getType());
104113
args[i] = tc.convertIfNecessary(value, td.getType(), td);
105114
}
106115
}

spring-jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.sql.Connection;
2121
import java.sql.ResultSet;
2222
import java.sql.ResultSetMetaData;
23+
import java.sql.SQLException;
2324
import java.sql.SQLFeatureNotSupportedException;
2425
import java.sql.Statement;
2526
import java.sql.Timestamp;
@@ -63,7 +64,7 @@ protected void verifyPerson(Person person) {
6364
protected void verifyPerson(ConcretePerson person) {
6465
assertThat(person.getName()).isEqualTo("Bubba");
6566
assertThat(person.getAge()).isEqualTo(22L);
66-
assertThat(person.getBirth_date()).usingComparator(Date::compareTo).isEqualTo(new java.util.Date(1221222L));
67+
assertThat(person.getBirthDate()).usingComparator(Date::compareTo).isEqualTo(new java.util.Date(1221222L));
6768
assertThat(person.getBalance()).isEqualTo(new BigDecimal("1234.56"));
6869
verifyPersonViaBeanWrapper(person);
6970
}
@@ -94,7 +95,14 @@ private void verifyPersonViaBeanWrapper(Object person) {
9495
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(person);
9596
assertThat(bw.getPropertyValue("name")).isEqualTo("Bubba");
9697
assertThat(bw.getPropertyValue("age")).isEqualTo(22L);
97-
assertThat((Date) bw.getPropertyValue("birth_date")).usingComparator(Date::compareTo).isEqualTo(new java.util.Date(1221222L));
98+
Date birthDate;
99+
if (bw.isReadableProperty("birth_date")) {
100+
birthDate = (Date) bw.getPropertyValue("birth_date");
101+
}
102+
else {
103+
birthDate = (Date) bw.getPropertyValue("birthDate");
104+
}
105+
assertThat(birthDate).usingComparator(Date::compareTo).isEqualTo(new java.util.Date(1221222L));
98106
assertThat(bw.getPropertyValue("balance")).isEqualTo(new BigDecimal("1234.56"));
99107
}
100108

@@ -107,7 +115,7 @@ protected void verifyPerson(EmailPerson person) {
107115
}
108116

109117

110-
protected enum MockType {ONE, TWO, THREE}
118+
protected enum MockType {ONE, TWO, THREE, FOUR}
111119

112120

113121
protected static class Mock {
@@ -152,13 +160,19 @@ public Mock(MockType type) throws Exception {
152160
given(resultSetMetaData.getColumnLabel(1)).willReturn(
153161
type == MockType.THREE ? "Last Name" : "name");
154162
given(resultSetMetaData.getColumnLabel(2)).willReturn("age");
155-
given(resultSetMetaData.getColumnLabel(3)).willReturn("birth_date");
163+
given(resultSetMetaData.getColumnLabel(3)).willReturn(type == MockType.FOUR ? "birthdate" :"birth_date");
156164
given(resultSetMetaData.getColumnLabel(4)).willReturn("balance");
157165
given(resultSetMetaData.getColumnLabel(5)).willReturn("e_mail");
158166

159167
given(resultSet.findColumn("name")).willReturn(1);
160168
given(resultSet.findColumn("age")).willReturn(2);
161-
given(resultSet.findColumn("birth_date")).willReturn(3);
169+
if (type == MockType.FOUR) {
170+
given(resultSet.findColumn("birthdate")).willReturn(3);
171+
}
172+
else {
173+
given(resultSet.findColumn("birthdate")).willThrow(new SQLException());
174+
given(resultSet.findColumn("birth_date")).willReturn(3);
175+
}
162176
given(resultSet.findColumn("balance")).willReturn(4);
163177
given(resultSet.findColumn("e_mail")).willReturn(5);
164178

spring-jdbc/src/test/java/org/springframework/jdbc/core/BeanPropertyRowMapperTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,17 @@ void queryWithSpaceInColumnNameAndLocalDate() throws Exception {
140140
mock.verifyClosed();
141141
}
142142

143+
@Test
144+
void queryWithDirectNameMatchOnBirthDate() throws Exception {
145+
Mock mock = new Mock(MockType.FOUR);
146+
List<ConcretePerson> result = mock.getJdbcTemplate().query(
147+
"select name, age, birthdate, balance from people",
148+
new BeanPropertyRowMapper<>(ConcretePerson.class));
149+
assertThat(result).hasSize(1);
150+
verifyPerson(result.get(0));
151+
mock.verifyClosed();
152+
}
153+
143154
@Test
144155
void queryWithUnderscoreInColumnNameAndPersonWithMultipleAdjacentUppercaseLettersInPropertyName() throws Exception {
145156
Mock mock = new Mock();

spring-jdbc/src/test/java/org/springframework/jdbc/core/DataClassRowMapperTests.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -57,23 +57,23 @@ public void testStaticQueryWithDataClassAndGenerics() throws Exception {
5757
ConstructorPersonWithGenerics person = result.get(0);
5858
assertThat(person.name()).isEqualTo("Bubba");
5959
assertThat(person.age()).isEqualTo(22L);
60-
assertThat(person.birth_date()).usingComparator(Date::compareTo).isEqualTo(new java.util.Date(1221222L));
60+
assertThat(person.birthDate()).usingComparator(Date::compareTo).isEqualTo(new java.util.Date(1221222L));
6161
assertThat(person.balance()).isEqualTo(Collections.singletonList(new BigDecimal("1234.56")));
6262

6363
mock.verifyClosed();
6464
}
6565

6666
@Test
6767
public void testStaticQueryWithDataClassAndSetters() throws Exception {
68-
Mock mock = new Mock();
68+
Mock mock = new Mock(MockType.FOUR);
6969
List<ConstructorPersonWithSetters> result = mock.getJdbcTemplate().query(
70-
"select name, age, birth_date, balance from people",
70+
"select name, age, birthdate, balance from people",
7171
new DataClassRowMapper<>(ConstructorPersonWithSetters.class));
7272
assertThat(result.size()).isEqualTo(1);
7373
ConstructorPersonWithSetters person = result.get(0);
7474
assertThat(person.name()).isEqualTo("BUBBA");
7575
assertThat(person.age()).isEqualTo(22L);
76-
assertThat(person.birth_date()).usingComparator(Date::compareTo).isEqualTo(new java.util.Date(1221222L));
76+
assertThat(person.birthDate()).usingComparator(Date::compareTo).isEqualTo(new java.util.Date(1221222L));
7777
assertThat(person.balance()).isEqualTo(new BigDecimal("1234.56"));
7878

7979
mock.verifyClosed();

spring-jdbc/src/test/java/org/springframework/jdbc/core/test/AbstractPerson.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -27,7 +27,7 @@ public abstract class AbstractPerson {
2727

2828
private long age;
2929

30-
private Date birth_date;
30+
private Date birthDate;
3131

3232

3333
public String getName() {
@@ -46,12 +46,12 @@ public void setAge(long age) {
4646
this.age = age;
4747
}
4848

49-
public Date getBirth_date() {
50-
return birth_date;
49+
public Date getBirthDate() {
50+
return birthDate;
5151
}
5252

53-
public void setBirth_date(Date birth_date) {
54-
this.birth_date = birth_date;
53+
public void setBirthDate(Date birthDate) {
54+
this.birthDate = birthDate;
5555
}
5656

5757
}

spring-jdbc/src/test/java/org/springframework/jdbc/core/test/ConstructorPersonWithGenerics.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -29,15 +29,15 @@ public class ConstructorPersonWithGenerics {
2929

3030
private final long age;
3131

32-
private final Date birth_date;
32+
private final Date birthDate;
3333

3434
private final List<BigDecimal> balance;
3535

3636

3737
public ConstructorPersonWithGenerics(String name, long age, Date birth_date, List<BigDecimal> balance) {
3838
this.name = name;
3939
this.age = age;
40-
this.birth_date = birth_date;
40+
this.birthDate = birth_date;
4141
this.balance = balance;
4242
}
4343

@@ -50,8 +50,8 @@ public long age() {
5050
return this.age;
5151
}
5252

53-
public Date birth_date() {
54-
return this.birth_date;
53+
public Date birthDate() {
54+
return this.birthDate;
5555
}
5656

5757
public List<BigDecimal> balance() {

spring-jdbc/src/test/java/org/springframework/jdbc/core/test/ConstructorPersonWithSetters.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -28,15 +28,15 @@ public class ConstructorPersonWithSetters {
2828

2929
private long age;
3030

31-
private Date birth_date;
31+
private Date birthDate;
3232

3333
private BigDecimal balance;
3434

3535

36-
public ConstructorPersonWithSetters(String name, long age, Date birth_date, BigDecimal balance) {
36+
public ConstructorPersonWithSetters(String name, long age, Date birthDate, BigDecimal balance) {
3737
this.name = name.toUpperCase();
3838
this.age = age;
39-
this.birth_date = birth_date;
39+
this.birthDate = birthDate;
4040
this.balance = balance;
4141
}
4242

@@ -49,8 +49,8 @@ public void setAge(long age) {
4949
this.age = age;
5050
}
5151

52-
public void setBirth_date(Date birth_date) {
53-
this.birth_date = birth_date;
52+
public void setBirthDate(Date birthDate) {
53+
this.birthDate = birthDate;
5454
}
5555

5656
public void setBalance(BigDecimal balance) {
@@ -65,8 +65,8 @@ public long age() {
6565
return this.age;
6666
}
6767

68-
public Date birth_date() {
69-
return this.birth_date;
68+
public Date birthDate() {
69+
return this.birthDate;
7070
}
7171

7272
public BigDecimal balance() {

spring-jdbc/src/test/java/org/springframework/jdbc/core/test/SpacePerson.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -60,8 +60,8 @@ public BigDecimal getBalance() {
6060
return balance;
6161
}
6262

63-
public void setBalance(BigDecimal balanace) {
64-
this.balance = balanace;
63+
public void setBalance(BigDecimal balance) {
64+
this.balance = balance;
6565
}
6666

6767
}

0 commit comments

Comments
 (0)