Skip to content

Commit

Permalink
DataClassRowMapper exposes generic constructor parameters for type co…
Browse files Browse the repository at this point in the history
…nversion

Closes spring-projectsgh-26881
  • Loading branch information
jhoeller committed May 11, 2021
1 parent cd9cad3 commit be52ec8
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
Expand All @@ -22,7 +22,9 @@

import org.springframework.beans.BeanUtils;
import org.springframework.beans.TypeConverter;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

Expand Down Expand Up @@ -50,7 +52,7 @@ public class DataClassRowMapper<T> extends BeanPropertyRowMapper<T> {
private String[] constructorParameterNames;

@Nullable
private Class<?>[] constructorParameterTypes;
private TypeDescriptor[] constructorParameterTypes;


/**
Expand All @@ -75,9 +77,13 @@ protected void initialize(Class<T> mappedClass) {
super.initialize(mappedClass);

this.mappedConstructor = BeanUtils.getResolvableConstructor(mappedClass);
if (this.mappedConstructor.getParameterCount() > 0) {
int paramCount = this.mappedConstructor.getParameterCount();
if (paramCount > 0) {
this.constructorParameterNames = BeanUtils.getParameterNames(this.mappedConstructor);
this.constructorParameterTypes = this.mappedConstructor.getParameterTypes();
this.constructorParameterTypes = new TypeDescriptor[paramCount];
for (int i = 0; i < paramCount; i++) {
this.constructorParameterTypes[i] = new TypeDescriptor(new MethodParameter(this.mappedConstructor, i));
}
}
}

Expand All @@ -90,8 +96,9 @@ protected T constructMappedInstance(ResultSet rs, TypeConverter tc) throws SQLEx
args = new Object[this.constructorParameterNames.length];
for (int i = 0; i < args.length; i++) {
String name = underscoreName(this.constructorParameterNames[i]);
Class<?> type = this.constructorParameterTypes[i];
args[i] = tc.convertIfNecessary(getColumnValue(rs, rs.findColumn(name), type), type);
TypeDescriptor td = this.constructorParameterTypes[i];
Object value = getColumnValue(rs, rs.findColumn(name), td.getType());
args[i] = tc.convertIfNecessary(value, td.getType(), td);
}
}
else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
Expand Down Expand Up @@ -135,6 +135,7 @@ public Mock(MockType type) throws Exception {
given(resultSet.getObject(anyInt(), any(Class.class))).willThrow(new SQLFeatureNotSupportedException());
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.wasNull()).willReturn(type == MockType.TWO);

given(resultSetMetaData.getColumnCount()).willReturn(4);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
Expand All @@ -16,11 +16,15 @@

package org.springframework.jdbc.core;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.junit.jupiter.api.Test;

import org.springframework.jdbc.core.test.ConstructorPerson;
import org.springframework.jdbc.core.test.ConstructorPersonWithGenerics;

import static org.assertj.core.api.Assertions.assertThat;

Expand All @@ -42,4 +46,20 @@ public void testStaticQueryWithDataClass() throws Exception {
mock.verifyClosed();
}

@Test
public void testStaticQueryWithDataClassAndGenerics() throws Exception {
Mock mock = new Mock();
List<ConstructorPersonWithGenerics> result = mock.getJdbcTemplate().query(
"select name, age, birth_date, balance from people",
new DataClassRowMapper<>(ConstructorPersonWithGenerics.class));
assertThat(result.size()).isEqualTo(1);
ConstructorPersonWithGenerics person = result.get(0);
assertThat(person.name()).isEqualTo("Bubba");
assertThat(person.age()).isEqualTo(22L);
assertThat(person.birth_date()).usingComparator(Date::compareTo).isEqualTo(new java.util.Date(1221222L));
assertThat(person.balance()).isEqualTo(Collections.singletonList(new BigDecimal("1234.56")));

mock.verifyClosed();
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
Expand All @@ -24,13 +24,13 @@
*/
public class ConstructorPerson {

private String name;
private final String name;

private long age;
private final long age;

private java.util.Date birth_date;
private final Date birth_date;

private BigDecimal balance;
private final BigDecimal balance;


public ConstructorPerson(String name, long age, Date birth_date, BigDecimal balance) {
Expand All @@ -42,19 +42,19 @@ public ConstructorPerson(String name, long age, Date birth_date, BigDecimal bala


public String name() {
return name;
return this.name;
}

public long age() {
return age;
return this.age;
}

public Date birth_date() {
return birth_date;
return this.birth_date;
}

public BigDecimal balance() {
return balance;
return this.balance;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2002-2021 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;
import java.util.List;

/**
* @author Juergen Hoeller
*/
public class ConstructorPersonWithGenerics {

private final String name;

private final long age;

private final Date birth_date;

private final List<BigDecimal> balance;


public ConstructorPersonWithGenerics(String name, long age, Date birth_date, List<BigDecimal> balance) {
this.name = name;
this.age = age;
this.birth_date = birth_date;
this.balance = balance;
}


public String name() {
return this.name;
}

public long age() {
return this.age;
}

public Date birth_date() {
return this.birth_date;
}

public List<BigDecimal> balance() {
return this.balance;
}

}

0 comments on commit be52ec8

Please sign in to comment.