Polishing

This commit is contained in:
Sam Brannen 2023-06-06 16:03:22 +02:00
parent 66a1be2d86
commit b9e972c248
6 changed files with 103 additions and 94 deletions

View File

@ -274,7 +274,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
/** /**
* Convert the given name to lower case. * Convert the given name to lower case.
* By default, conversions will happen within the US locale. * <p>By default, conversions will happen within the US locale.
* @param name the original name * @param name the original name
* @return the converted name * @return the converted name
* @since 4.2 * @since 4.2
@ -285,7 +285,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
/** /**
* Convert a name in camelCase to an underscored name in lower case. * Convert a name in camelCase to an underscored name in lower case.
* Any upper case letters are converted to lower case with a preceding underscore. * <p>Any upper case letters are converted to lower case with a preceding underscore.
* @param name the original name * @param name the original name
* @return the converted name * @return the converted name
* @since 4.2 * @since 4.2
@ -390,7 +390,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
/** /**
* Initialize the given BeanWrapper to be used for row mapping. * Initialize the given BeanWrapper to be used for row mapping.
* To be called for each row. * <p>To be called for each row.
* <p>The default implementation applies the configured {@link ConversionService}, * <p>The default implementation applies the configured {@link ConversionService},
* if any. Can be overridden in subclasses. * if any. Can be overridden in subclasses.
* @param bw the BeanWrapper to initialize * @param bw the BeanWrapper to initialize

View File

@ -48,47 +48,46 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* Mapping {@code Function} implementation that converts an R2DBC {@code Readable} * Mapping {@code Function} implementation that converts an R2DBC {@link Readable}
* (a {@code Row} or {@code OutParameters}) into a new instance of the specified mapped * (a {@link Row} or {@link OutParameters}) into a new instance of the specified mapped
* target class. The mapped target class must be a top-level class or {@code static} * target class. The mapped target class must be a top-level class or {@code static}
* nested class, and it must have a default or no-arg constructor. * nested class, and it must have a default or no-arg constructor.
* *
* <p> * <p>{@code Readable} component values are mapped based on matching the column
* Readable component values are mapped based on matching the name (as obtained from R2DBC * name (as obtained from R2DBC meta-data) to public setters in the target class
* meta-data) to public setters in the target class for the corresponding properties. The * for the corresponding properties. The names are matched either directly or by
* names are matched either directly or by transforming a name separating the parts with * transforming a name separating the parts with underscores to the same name using
* underscores to the same name using "camel" case. * "camel" case.
* *
* <p> * <p>Mapping is provided for properties in the target class for many common types &mdash;
* Mapping is provided for properties in the target class for many common types &mdash; * for example: String, boolean, Boolean, byte, Byte, short, Short, int, Integer,
* for example: String, boolean, Boolean, byte, Byte, short, Short, int, Integer, long, * long, Long, float, Float, double, Double, BigDecimal, {@code java.util.Date}, etc.
* Long, float, Float, double, Double, BigDecimal, {@code java.util.Date}, etc.
* *
* <p> * <p>To facilitate mapping between columns and properties that don't have matching
* To facilitate mapping between columns and properties that don't have matching names, * names, try using column aliases in the SQL statement like
* try using column aliases in the SQL statement like * {@code "select fname as first_name from customer"}, where {@code first_name}
* {@code "select fname as first_name from customer"}, where {@code first_name} can be * can be mapped to a {@code setFirstName(String)} method in the target class.
* mapped to a {@code setFirstName(String)} method in the target class.
* *
* <p> * <p>For a {@code NULL} value read from the database, an attempt will be made to
* For a {@code NULL} value read from the database, an attempt will be made to call the * call the corresponding setter method with {@code null}, but in the case of
* corresponding setter method with {@code null}, but in the case of Java primitives this * Java primitives this will result in a {@link TypeMismatchException} by default.
* will result in a {@link TypeMismatchException} by default. To ignore {@code NULL} * To ignore {@code NULL} database values for all primitive properties in the
* database values for all primitive properties in the target class, set the * target class, set the {@code primitivesDefaultedForNullValue} flag to
* {@code primitivesDefaultedForNullValue} flag to {@code true}. See * {@code true}. See {@link #setPrimitivesDefaultedForNullValue(boolean)} for
* {@link #setPrimitivesDefaultedForNullValue(boolean)} for details. * details.
* *
* <p> * <p>If you need to map to a target class which has a <em>data class</em> constructor
* If you need to map to a target class which has a <em>data class</em> constructor * &mdash; for example, a Java {@code record} or a Kotlin {@code data} class &mdash;
* &mdash; for example, a Java {@code record} or a Kotlin {@code data} class &mdash; use * use {@link DataClassRowMapper} instead.
* {@link DataClassRowMapper} instead.
* *
* <p> * <p>Please note that this class is designed to provide convenience rather than
* Please note that this class is designed to provide convenience rather than high * high performance. For best performance, consider using a custom mapping function
* performance. For best performance, consider using a custom mapping function
* implementation. * implementation.
* *
* @author Simon Baslé * @author Simon Baslé
* @author Thomas Risberg
* @author Juergen Hoeller
* @author Sam Brannen
* @since 6.1 * @since 6.1
* @param <T> the result type * @param <T> the result type
* @see DataClassRowMapper * @see DataClassRowMapper
@ -254,7 +253,7 @@ public class BeanPropertyRowMapper<T> implements Function<Readable, T> {
/** /**
* Convert the given name to lower case. * Convert the given name to lower case.
* By default, conversions will happen within the US locale. * <p>By default, conversions will happen within the US locale.
* @param name the original name * @param name the original name
* @return the converted name * @return the converted name
*/ */
@ -264,7 +263,7 @@ public class BeanPropertyRowMapper<T> implements Function<Readable, T> {
/** /**
* Convert a name in camelCase to an underscored name in lower case. * Convert a name in camelCase to an underscored name in lower case.
* Any upper case letters are converted to lower case with a preceding underscore. * <p>Any upper case letters are converted to lower case with a preceding underscore.
* @param name the original name * @param name the original name
* @return the converted name * @return the converted name
* @see #lowerCaseName * @see #lowerCaseName
@ -289,13 +288,11 @@ public class BeanPropertyRowMapper<T> implements Function<Readable, T> {
} }
/** /**
* Extract the values for the current {@code Readable} : * Extract the values for the current {@link Readable}: all columns in case
* all columns in case of a {@code Row} or all parameters in * of a {@link Row} or all parameters in case of an {@link OutParameters}.
* case of an {@code OutParameters}. * <p>Utilizes public setters and derives meta-data from the concrete type.
* <p>Utilizes public setters and derives meta-data from the * @throws IllegalArgumentException in case the concrete type is neither
* concrete type. * {@code Row} nor {@code OutParameters}
* @throws UnsupportedOperationException in case the concrete type
* is neither {@code Row} nor {@code OutParameters}
* @see RowMetadata * @see RowMetadata
* @see OutParametersMetadata * @see OutParametersMetadata
*/ */
@ -326,7 +323,7 @@ public class BeanPropertyRowMapper<T> implements Function<Readable, T> {
PropertyDescriptor pd = (this.mappedProperties != null ? this.mappedProperties.get(property) : null); PropertyDescriptor pd = (this.mappedProperties != null ? this.mappedProperties.get(property) : null);
if (pd != null) { if (pd != null) {
Object value = getItemValue(readable, itemIndex, pd); Object value = getItemValue(readable, itemIndex, pd);
//Implementation note: the JDBC mapper can log the column mapping details each time row 0 is encountered // Implementation note: the JDBC mapper can log the column mapping details each time row 0 is encountered
// but unfortunately this is not possible in R2DBC as row number is not provided. The BiFunction#apply // but unfortunately this is not possible in R2DBC as row number is not provided. The BiFunction#apply
// cannot be stateful as it could be applied to a different row set, e.g. when resubscribing. // cannot be stateful as it could be applied to a different row set, e.g. when resubscribing.
try { try {
@ -363,9 +360,8 @@ public class BeanPropertyRowMapper<T> implements Function<Readable, T> {
/** /**
* Construct an instance of the mapped class for the current {@code Readable}. * Construct an instance of the mapped class for the current {@code Readable}.
* <p> * <p>The default implementation simply instantiates the mapped class. Can be
* The default implementation simply instantiates the mapped class. Can be overridden * overridden in subclasses.
* in subclasses.
* @param readable the {@code Readable} being mapped (a {@code Row} or {@code OutParameters}) * @param readable the {@code Readable} being mapped (a {@code Row} or {@code OutParameters})
* @param itemMetadatas the list of item {@code ReadableMetadata} (either * @param itemMetadatas the list of item {@code ReadableMetadata} (either
* {@code ColumnMetadata} or {@code OutParameterMetadata}) * {@code ColumnMetadata} or {@code OutParameterMetadata})
@ -380,7 +376,7 @@ public class BeanPropertyRowMapper<T> implements Function<Readable, T> {
/** /**
* Initialize the given BeanWrapper to be used for row mapping or outParameters * Initialize the given BeanWrapper to be used for row mapping or outParameters
* mapping. * mapping.
* To be called for each Readable. * <p>To be called for each Readable.
* <p>The default implementation applies the configured {@link ConversionService}, * <p>The default implementation applies the configured {@link ConversionService},
* if any. Can be overridden in subclasses. * if any. Can be overridden in subclasses.
* @param bw the BeanWrapper to initialize * @param bw the BeanWrapper to initialize
@ -395,7 +391,7 @@ public class BeanPropertyRowMapper<T> implements Function<Readable, T> {
} }
/** /**
* Retrieve a R2DBC object value for the specified item index (a column or an * Retrieve an R2DBC object value for the specified item index (a column or an
* out-parameter). * out-parameter).
* <p>The default implementation delegates to * <p>The default implementation delegates to
* {@link #getItemValue(Readable, int, Class)}. * {@link #getItemValue(Readable, int, Class)}.
@ -411,12 +407,12 @@ public class BeanPropertyRowMapper<T> implements Function<Readable, T> {
} }
/** /**
* Retrieve a R2DBC object value for the specified item index (a column or * Retrieve an R2DBC object value for the specified item index (a column or
* an out-parameter). * an out-parameter).
* <p>The default implementation calls {@link Readable#get(int, Class)} then * <p>The default implementation calls {@link Readable#get(int, Class)} then
* falls back to {@link Readable#get(int)} in case of an exception. * falls back to {@link Readable#get(int)} in case of an exception.
* Subclasses may override this to check specific value types upfront, * Subclasses may override this to check specific value types upfront,
* or to post-process values return from {@code get}. * or to post-process values returned from {@code get}.
* @param readable is the {@code Row} or {@code OutParameters} holding the data * @param readable is the {@code Row} or {@code OutParameters} holding the data
* @param itemIndex is the column index or out-parameter index * @param itemIndex is the column index or out-parameter index
* @param paramType the target parameter type * @param paramType the target parameter type

View File

@ -32,35 +32,34 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* Mapping {@code Function} implementation that converts an R2DBC {@code Readable} * Mapping {@code Function} implementation that converts an R2DBC {@link Readable}
* (a {@code Row} or {@code OutParameters}) into a new instance of the specified mapped * (a {@link io.r2dbc.spi.Row Row} or {@link io.r2dbc.spi.OutParameters OutParameters})
* target class. The mapped target class must be a top-level class or {@code static} * into a new instance of the specified mapped target class. The mapped target class
* nested class, and it may expose either a <em>data class</em> constructor with named * must be a top-level class or {@code static} nested class, and it may expose either
* parameters corresponding to column names or classic bean property setter methods * a <em>data class</em> constructor with named parameters corresponding to column
* with property names corresponding to column names (or even a combination of both). * names or classic bean property setter methods with property names corresponding
* to column names (or even a combination of both).
* *
* <p> * <p>The term "data class" applies to Java <em>records</em>, Kotlin <em>data
* The term "data class" applies to Java <em>records</em>, Kotlin <em>data classes</em>, * classes</em>, and any class which has a constructor with named parameters
* and any class which has a constructor with named parameters that are intended to be * that are intended to be mapped to corresponding column names.
* mapped to corresponding column names.
* *
* <p> * <p>When combining a data class constructor with setter methods, any property
* When combining a data class constructor with setter methods, any property mapped * mapped successfully via a constructor argument will not be mapped additionally
* successfully via a constructor argument will not be mapped additionally via a * via a corresponding setter method. This means that constructor arguments take
* corresponding setter method. This means that constructor arguments take precedence over * precedence over property setter methods.
* property setter methods.
* *
* <p> * <p>Note that this class extends {@link BeanPropertyRowMapper} and can
* Note that this class extends {@link BeanPropertyRowMapper} and can therefore serve as a * therefore serve as a common choice for any mapped target class, flexibly
* common choice for any mapped target class, flexibly adapting to constructor style * adapting to constructor style versus setter methods in the mapped class.
* versus setter methods in the mapped class.
* *
* <p> * <p>Please note that this class is designed to provide convenience rather than
* Please note that this class is designed to provide convenience rather than high * high performance. For best performance, consider using a custom readable mapping
* performance. For best performance, consider using a custom readable mapping
* {@code Function} implementation. * {@code Function} implementation.
* *
* @author Simon Baslé * @author Simon Baslé
* @author Juergen Hoeller
* @author Sam Brannen
* @since 6.1 * @since 6.1
* @param <T> the result type * @param <T> the result type
*/ */
@ -135,7 +134,7 @@ public class DataClassRowMapper<T> extends BeanPropertyRowMapper<T> {
private int findIndex(Readable readable, List<? extends ReadableMetadata> itemMetadatas, String name) { private int findIndex(Readable readable, List<? extends ReadableMetadata> itemMetadatas, String name) {
int index = 0; int index = 0;
for (ReadableMetadata itemMetadata : itemMetadatas) { for (ReadableMetadata itemMetadata : itemMetadatas) {
//we use equalsIgnoreCase, similarly to RowMetadata#contains(String) // we use equalsIgnoreCase, similar to RowMetadata#contains(String)
if (itemMetadata.getName().equalsIgnoreCase(name)) { if (itemMetadata.getName().equalsIgnoreCase(name)) {
return index; return index;
} }

View File

@ -34,25 +34,30 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatNoException;
class BeanPropertyRowMapperTests { /**
* Tests for R2DBC-based {@link BeanPropertyRowMapper}.
*
* @since 6.1
*/
class R2dbcBeanPropertyRowMapperTests {
@Test @Test
void mappingUnknownReadableRejected() { void mappingUnknownReadableRejected() {
final BeanPropertyRowMapper<Person> mapper = new BeanPropertyRowMapper<>(Person.class); BeanPropertyRowMapper<Person> mapper = new BeanPropertyRowMapper<>(Person.class);
assertThatIllegalArgumentException().isThrownBy(() -> mapper.apply(Mockito.mock(Readable.class))) assertThatIllegalArgumentException().isThrownBy(() -> mapper.apply(Mockito.mock(Readable.class)))
.withMessageStartingWith("Can only map Readable Row or OutParameters, got io.r2dbc.spi.Readable$MockitoMock$"); .withMessageStartingWith("Can only map Readable Row or OutParameters, got io.r2dbc.spi.Readable$MockitoMock$");
} }
@Test @Test
void mappingOutParametersAccepted() { void mappingOutParametersAccepted() {
final BeanPropertyRowMapper<Person> mapper = new BeanPropertyRowMapper<>(Person.class); BeanPropertyRowMapper<Person> mapper = new BeanPropertyRowMapper<>(Person.class);
assertThatNoException().isThrownBy(() -> mapper.apply(MockOutParameters.empty())); assertThatNoException().isThrownBy(() -> mapper.apply(MockOutParameters.empty()));
} }
@Test @Test
void mappingRowSimpleObject() { void mappingRowSimpleObject() {
MockRow mockRow = SIMPLE_PERSON_ROW; MockRow mockRow = SIMPLE_PERSON_ROW;
final BeanPropertyRowMapper<Person> mapper = new BeanPropertyRowMapper<>(Person.class); BeanPropertyRowMapper<Person> mapper = new BeanPropertyRowMapper<>(Person.class);
Person result = mapper.apply(mockRow); Person result = mapper.apply(mockRow);
@ -64,7 +69,7 @@ class BeanPropertyRowMapperTests {
@Test @Test
void mappingRowMissingAttributeAccepted() { void mappingRowMissingAttributeAccepted() {
MockRow mockRow = SIMPLE_PERSON_ROW; MockRow mockRow = SIMPLE_PERSON_ROW;
final BeanPropertyRowMapper<ExtendedPerson> mapper = new BeanPropertyRowMapper<>(ExtendedPerson.class); BeanPropertyRowMapper<ExtendedPerson> mapper = new BeanPropertyRowMapper<>(ExtendedPerson.class);
ExtendedPerson result = mapper.apply(mockRow); ExtendedPerson result = mapper.apply(mockRow);
@ -77,7 +82,7 @@ class BeanPropertyRowMapperTests {
@Test @Test
void mappingRowWithDifferentName() { void mappingRowWithDifferentName() {
MockRow mockRow = EMAIL_PERSON_ROW; MockRow mockRow = EMAIL_PERSON_ROW;
final BeanPropertyRowMapper<EmailPerson> mapper = new BeanPropertyRowMapper<>(EmailPerson.class); BeanPropertyRowMapper<EmailPerson> mapper = new BeanPropertyRowMapper<>(EmailPerson.class);
EmailPerson result = mapper.apply(mockRow); EmailPerson result = mapper.apply(mockRow);
@ -89,21 +94,22 @@ class BeanPropertyRowMapperTests {
@Test @Test
void mappingRowMissingAttributeRejected() { void mappingRowMissingAttributeRejected() {
Class<ExtendedPerson> mappedClass = ExtendedPerson.class;
MockRow mockRow = SIMPLE_PERSON_ROW; MockRow mockRow = SIMPLE_PERSON_ROW;
final BeanPropertyRowMapper<ExtendedPerson> mapper = new BeanPropertyRowMapper<>(ExtendedPerson.class, true); BeanPropertyRowMapper<ExtendedPerson> mapper = new BeanPropertyRowMapper<>(mappedClass, true);
assertThatExceptionOfType(InvalidDataAccessApiUsageException.class) assertThatExceptionOfType(InvalidDataAccessApiUsageException.class)
.isThrownBy(() -> mapper.apply(mockRow)) .isThrownBy(() -> mapper.apply(mockRow))
.withMessage("Given readable does not contain all items necessary to populate object of class org.springframework." .withMessage("Given readable does not contain all items necessary to populate object of %s"
+ "r2dbc.core.BeanPropertyRowMapperTests$ExtendedPerson: [firstName, lastName, address, age]"); + ": [firstName, lastName, address, age]", mappedClass);
} }
//TODO cannot trigger a mapping of a read-only property, as mappedProperties don't include properties without a setter. // TODO cannot trigger a mapping of a read-only property, as mappedProperties don't include properties without a setter.
@Test @Test
void rowTypeAndMappingTypeMisaligned() { void rowTypeAndMappingTypeMisaligned() {
MockRow mockRow = EXTENDED_PERSON_ROW; MockRow mockRow = EXTENDED_PERSON_ROW;
final BeanPropertyRowMapper<TypeMismatchExtendedPerson> mapper = new BeanPropertyRowMapper<>(TypeMismatchExtendedPerson.class); BeanPropertyRowMapper<TypeMismatchExtendedPerson> mapper = new BeanPropertyRowMapper<>(TypeMismatchExtendedPerson.class);
assertThatExceptionOfType(TypeMismatchException.class) assertThatExceptionOfType(TypeMismatchException.class)
.isThrownBy(() -> mapper.apply(mockRow)) .isThrownBy(() -> mapper.apply(mockRow))
@ -124,7 +130,7 @@ class BeanPropertyRowMapperTests {
.identified(2, int.class, null) .identified(2, int.class, null)
.identified(3, String.class, "123 Sesame Street") .identified(3, String.class, "123 Sesame Street")
.build(); .build();
final BeanPropertyRowMapper<Person> mapper = new BeanPropertyRowMapper<>(Person.class); BeanPropertyRowMapper<Person> mapper = new BeanPropertyRowMapper<>(Person.class);
mapper.setPrimitivesDefaultedForNullValue(true); mapper.setPrimitivesDefaultedForNullValue(true);
Person result = mapper.apply(mockRow); Person result = mapper.apply(mockRow);
@ -147,6 +153,7 @@ class BeanPropertyRowMapperTests {
} }
@SuppressWarnings("unused")
private static class Person { private static class Person {
String firstName; String firstName;
@ -181,6 +188,7 @@ class BeanPropertyRowMapperTests {
} }
@SuppressWarnings("unused")
private static class ExtendedPerson extends Person { private static class ExtendedPerson extends Person {
String address; String address;
@ -204,6 +212,7 @@ class BeanPropertyRowMapperTests {
} }
@SuppressWarnings("unused")
private static class EmailPerson extends Person { private static class EmailPerson extends Person {
String email; String email;

View File

@ -27,12 +27,17 @@ import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
class DataClassRowMapperTests { /**
* Test for R2DBC-based {@link DataClassRowMapper}.
*
* @since 6.1
*/
class R2dbcDataClassRowMapperTests {
@Test @Test
void staticQueryWithDataClass() { void staticQueryWithDataClass() {
MockRow mockRow = MOCK_ROW; // uses name, age, birth_date MockRow mockRow = MOCK_ROW; // uses name, age, birth_date
final DataClassRowMapper<ConstructorPerson> mapper = new DataClassRowMapper<>(ConstructorPerson.class); DataClassRowMapper<ConstructorPerson> mapper = new DataClassRowMapper<>(ConstructorPerson.class);
ConstructorPerson person = mapper.apply(mockRow); ConstructorPerson person = mapper.apply(mockRow);
@ -44,8 +49,8 @@ class DataClassRowMapperTests {
@Test @Test
void staticQueryWithDataClassAndGenerics() { void staticQueryWithDataClassAndGenerics() {
MockRow mockRow = buildMockRow("birth_date", true); // uses name, age, birth_date, balance (as list) MockRow mockRow = buildMockRow("birth_date", true); // uses name, age, birth_date, balance (as list)
//TODO validate actual R2DBC Row implementations would return something for balance if asking a List // TODO validate actual R2DBC Row implementations would return something for balance if requesting a List
final DataClassRowMapper<ConstructorPersonWithGenerics> mapper = new DataClassRowMapper<>(ConstructorPersonWithGenerics.class); DataClassRowMapper<ConstructorPersonWithGenerics> mapper = new DataClassRowMapper<>(ConstructorPersonWithGenerics.class);
ConstructorPersonWithGenerics person = mapper.apply(mockRow); ConstructorPersonWithGenerics person = mapper.apply(mockRow);
assertThat(person.name()).isEqualTo("Bubba"); assertThat(person.name()).isEqualTo("Bubba");
@ -57,7 +62,7 @@ class DataClassRowMapperTests {
@Test @Test
void staticQueryWithDataRecord() { void staticQueryWithDataRecord() {
MockRow mockRow = MOCK_ROW; // uses name, age, birth_date, balance MockRow mockRow = MOCK_ROW; // uses name, age, birth_date, balance
final DataClassRowMapper<RecordPerson> mapper = new DataClassRowMapper<>(RecordPerson.class); DataClassRowMapper<RecordPerson> mapper = new DataClassRowMapper<>(RecordPerson.class);
RecordPerson person = mapper.apply(mockRow); RecordPerson person = mapper.apply(mockRow);
assertThat(person.name()).isEqualTo("Bubba"); assertThat(person.name()).isEqualTo("Bubba");
@ -69,7 +74,7 @@ class DataClassRowMapperTests {
@Test @Test
void staticQueryWithDataClassAndSetters() { void staticQueryWithDataClassAndSetters() {
MockRow mockRow = buildMockRow("birthdate", false); // uses name, age, birthdate (no underscore), balance MockRow mockRow = buildMockRow("birthdate", false); // uses name, age, birthdate (no underscore), balance
final DataClassRowMapper<ConstructorPersonWithSetters> mapper = new DataClassRowMapper<>(ConstructorPersonWithSetters.class); DataClassRowMapper<ConstructorPersonWithSetters> mapper = new DataClassRowMapper<>(ConstructorPersonWithSetters.class);
ConstructorPersonWithSetters person = mapper.apply(mockRow); ConstructorPersonWithSetters person = mapper.apply(mockRow);
assertThat(person.name()).isEqualTo("BUBBA"); assertThat(person.name()).isEqualTo("BUBBA");
@ -177,10 +182,10 @@ class DataClassRowMapperTests {
} }
static MockRow MOCK_ROW = buildMockRow("birth_date", false); static final MockRow MOCK_ROW = buildMockRow("birth_date", false);
private static MockRow buildMockRow(String birthDateColumnName, boolean balanceObjectIdentifier) { private static MockRow buildMockRow(String birthDateColumnName, boolean balanceObjectIdentifier) {
final MockRow.Builder builder = MockRow.builder(); MockRow.Builder builder = MockRow.builder();
builder.metadata(MockRowMetadata.builder() builder.metadata(MockRowMetadata.builder()
.columnMetadata(MockColumnMetadata.builder().name("name").javaType(String.class).build()) .columnMetadata(MockColumnMetadata.builder().name("name").javaType(String.class).build())
.columnMetadata(MockColumnMetadata.builder().name("age").javaType(long.class).build()) .columnMetadata(MockColumnMetadata.builder().name("age").javaType(long.class).build())

View File

@ -766,7 +766,7 @@ class RestTemplateTests {
given(request.getHeaders()).willReturn(requestHeaders); given(request.getHeaders()).willReturn(requestHeaders);
} }
@SuppressWarnings("deprecation") @SuppressWarnings({ "deprecation", "removal" })
private void mockResponseStatus(HttpStatus responseStatus) throws Exception { private void mockResponseStatus(HttpStatus responseStatus) throws Exception {
given(request.execute()).willReturn(response); given(request.execute()).willReturn(response);
given(errorHandler.hasError(response)).willReturn(responseStatus.isError()); given(errorHandler.hasError(response)).willReturn(responseStatus.isError());