Fix regression in BeanPropertyRowMapper.underscoreName(String)

Commit 6316a35 introduced a regression for property names starting with
multiple uppercase letters (such as setEMail(...)).

This commit fixes that regression and includes an additional test to
cover this case.

See gh-27929
Closes gh-27941
This commit is contained in:
Marten Deinum 2022-01-17 07:54:07 +01:00 committed by Sam Brannen
parent c92b9bc7fe
commit 261bc2ad6a
4 changed files with 108 additions and 5 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-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.
@ -273,7 +273,8 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < name.length(); i++) {
result.append(Character.toLowerCase(name.charAt(0)));
for (int i = 1; i < name.length(); i++) {
char c = name.charAt(i);
if (Character.isUpperCase(c)) {
result.append('_').append(Character.toLowerCase(c));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-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.
@ -30,6 +30,7 @@ import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.jdbc.core.test.ConcretePerson;
import org.springframework.jdbc.core.test.ConstructorPerson;
import org.springframework.jdbc.core.test.DatePerson;
import org.springframework.jdbc.core.test.EmailPerson;
import org.springframework.jdbc.core.test.Person;
import org.springframework.jdbc.core.test.SpacePerson;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
@ -97,6 +98,14 @@ public abstract class AbstractRowMapperTests {
assertThat(bw.getPropertyValue("balance")).isEqualTo(new BigDecimal("1234.56"));
}
protected void verifyPerson(EmailPerson person) {
assertThat(person.getName()).isEqualTo("Bubba");
assertThat(person.getAge()).isEqualTo(22L);
assertThat(person.getBirth_date()).usingComparator(Date::compareTo).isEqualTo(new java.util.Date(1221222L));
assertThat(person.getBalance()).isEqualTo(new BigDecimal("1234.56"));
assertThat(person.getEMail()).isEqualTo("hello@world.info");
}
protected enum MockType {ONE, TWO, THREE};
@ -136,19 +145,22 @@ public abstract class AbstractRowMapperTests {
given(resultSet.getDate(3)).willReturn(new java.sql.Date(1221222L));
given(resultSet.getBigDecimal(4)).willReturn(new BigDecimal("1234.56"));
given(resultSet.getObject(4)).willReturn(new BigDecimal("1234.56"));
given(resultSet.getString(5)).willReturn("hello@world.info");
given(resultSet.wasNull()).willReturn(type == MockType.TWO);
given(resultSetMetaData.getColumnCount()).willReturn(4);
given(resultSetMetaData.getColumnCount()).willReturn(5);
given(resultSetMetaData.getColumnLabel(1)).willReturn(
type == MockType.THREE ? "Last Name" : "name");
given(resultSetMetaData.getColumnLabel(2)).willReturn("age");
given(resultSetMetaData.getColumnLabel(3)).willReturn("birth_date");
given(resultSetMetaData.getColumnLabel(4)).willReturn("balance");
given(resultSetMetaData.getColumnLabel(5)).willReturn("e_mail");
given(resultSet.findColumn("name")).willReturn(1);
given(resultSet.findColumn("age")).willReturn(2);
given(resultSet.findColumn("birth_date")).willReturn(3);
given(resultSet.findColumn("balance")).willReturn(4);
given(resultSet.findColumn("e_mail")).willReturn(5);
jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(new SingleConnectionDataSource(connection, false));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-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.
@ -24,6 +24,7 @@ import org.springframework.beans.TypeMismatchException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.jdbc.core.test.ConcretePerson;
import org.springframework.jdbc.core.test.DatePerson;
import org.springframework.jdbc.core.test.EmailPerson;
import org.springframework.jdbc.core.test.ExtendedPerson;
import org.springframework.jdbc.core.test.Person;
import org.springframework.jdbc.core.test.SpacePerson;
@ -134,4 +135,15 @@ public class BeanPropertyRowMapperTests extends AbstractRowMapperTests {
mock.verifyClosed();
}
@Test
public void testQueryWithUnderscoreAndPersonWithMultipleAdjacentUppercaseLettersInPropertyName() throws Exception {
Mock mock = new Mock();
List<EmailPerson> result = mock.getJdbcTemplate().query(
"select name, age, birth_date, balance, e_mail from people",
new BeanPropertyRowMapper<>(EmailPerson.class));
assertThat(result.size()).isEqualTo(1);
verifyPerson(result.get(0));
mock.verifyClosed();
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright 2002-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.springframework.jdbc.core.test;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author Thomas Risberg
* @author Marten Deinum
*/
public class EmailPerson {
private String name;
private long age;
private Date birth_date;
private BigDecimal balance;
private String eMail;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getAge() {
return age;
}
public void setAge(long age) {
this.age = age;
}
public Date getBirth_date() {
return birth_date;
}
public void setBirth_date(Date birth_date) {
this.birth_date = birth_date;
}
public BigDecimal getBalance() {
return balance;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
public void setEMail(String email) {
this.eMail=email;
}
public String getEMail() {
return this.eMail;
}
}