Browse Source

Polishing.

Fix nullability issues.

See #2217

(cherry picked from commit 08c86dc94e)
pull/2219/head
Mark Paluch 2 weeks ago committed by 62hoon99
parent
commit
73ff9cc2e3
  1. 7
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/IterableOfEntryToMapConverter.java
  2. 7
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java
  3. 41
      spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/convert/R2dbcConverters.java
  4. 5
      spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/MySqlDialect.java
  5. 45
      spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java
  6. 11
      spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/TypedSubtreeVisitor.java

7
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/IterableOfEntryToMapConverter.java

@ -19,7 +19,6 @@ import java.util.HashMap; @@ -19,7 +19,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.jspecify.annotations.Nullable;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalConverter;
import org.springframework.core.convert.converter.Converter;
@ -32,16 +31,14 @@ import org.springframework.util.Assert; @@ -32,16 +31,14 @@ import org.springframework.util.Assert;
*/
class IterableOfEntryToMapConverter implements ConditionalConverter, Converter<Iterable<?>, Map<?, ?>> {
@SuppressWarnings("unchecked")
@Nullable
@Override
public Map<?, ?> convert(Iterable<?> source) {
Map result = new HashMap();
Map<Object, Object> result = new HashMap<>();
source.forEach(element -> {
if (element instanceof Entry entry) {
if (element instanceof Entry<?, ?> entry) {
result.put(entry.getKey(), entry.getValue());
return;
}

7
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java

@ -200,8 +200,7 @@ public class MappingJdbcConverter extends MappingRelationalConverter implements @@ -200,8 +200,7 @@ public class MappingJdbcConverter extends MappingRelationalConverter implements
* @return
*/
@Override
@Nullable
public Object readValue(@Nullable Object value, TypeInformation<?> targetType) {
public @Nullable Object readValue(@Nullable Object value, TypeInformation<?> targetType) {
if (null == value) {
return null;
@ -573,12 +572,12 @@ public class MappingJdbcConverter extends MappingRelationalConverter implements @@ -573,12 +572,12 @@ public class MappingJdbcConverter extends MappingRelationalConverter implements
Identifier identifier) implements ConversionContext {
@Override
public <S> S convert(Object source, TypeInformation<? extends S> typeHint) {
public <S> @Nullable S convert(Object source, TypeInformation<? extends S> typeHint) {
return delegate.convert(source, typeHint);
}
@Override
public <S> S convert(Object source, TypeInformation<? extends S> typeHint, ConversionContext context) {
public <S> @Nullable S convert(Object source, TypeInformation<? extends S> typeHint, ConversionContext context) {
return delegate.convert(source, typeHint, context);
}

41
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/convert/R2dbcConverters.java

@ -70,12 +70,12 @@ abstract class R2dbcConverters { @@ -70,12 +70,12 @@ abstract class R2dbcConverters {
*
* @author Hebert Coelho
*/
public enum RowToBooleanConverter implements Converter<Row, Boolean> {
public enum RowToBooleanConverter implements Converter<Row, @Nullable Boolean> {
INSTANCE;
@Override
public @Nullable Boolean convert(Row row) {
public Boolean convert(Row row) {
return row.get(0, Boolean.class);
}
}
@ -85,12 +85,12 @@ abstract class R2dbcConverters { @@ -85,12 +85,12 @@ abstract class R2dbcConverters {
*
* @author Hebert Coelho
*/
public enum RowToLocalDateConverter implements Converter<Row, LocalDate> {
public enum RowToLocalDateConverter implements Converter<Row, @Nullable LocalDate> {
INSTANCE;
@Override
public @Nullable LocalDate convert(Row row) {
public LocalDate convert(Row row) {
return row.get(0, LocalDate.class);
}
}
@ -100,12 +100,12 @@ abstract class R2dbcConverters { @@ -100,12 +100,12 @@ abstract class R2dbcConverters {
*
* @author Hebert Coelho
*/
public enum RowToLocalDateTimeConverter implements Converter<Row, LocalDateTime> {
public enum RowToLocalDateTimeConverter implements Converter<Row, @Nullable LocalDateTime> {
INSTANCE;
@Override
public @Nullable LocalDateTime convert(Row row) {
public LocalDateTime convert(Row row) {
return row.get(0, LocalDateTime.class);
}
}
@ -115,12 +115,12 @@ abstract class R2dbcConverters { @@ -115,12 +115,12 @@ abstract class R2dbcConverters {
*
* @author Hebert Coelho
*/
public enum RowToLocalTimeConverter implements Converter<Row, LocalTime> {
public enum RowToLocalTimeConverter implements Converter<Row, @Nullable LocalTime> {
INSTANCE;
@Override
public @Nullable LocalTime convert(Row row) {
public LocalTime convert(Row row) {
return row.get(0, LocalTime.class);
}
}
@ -141,20 +141,21 @@ abstract class R2dbcConverters { @@ -141,20 +141,21 @@ abstract class R2dbcConverters {
* @see java.math.BigDecimal
* @author Hebert Coelho
*/
public enum RowToNumberConverterFactory implements ConverterFactory<Row, Number> {
public enum RowToNumberConverterFactory implements ConverterFactory<Row, @Nullable Number> {
INSTANCE;
@Override
public <T extends Number> Converter<Row, T> getConverter(Class<T> targetType) {
public <T extends @Nullable Number> Converter<Row, T> getConverter(Class<T> targetType) {
Assert.notNull(targetType, "Target type must not be null");
return new RowToNumber<>(targetType);
}
record RowToNumber<T extends Number>(Class<T> targetType) implements Converter<Row, T> {
@SuppressWarnings("NullAway")
record RowToNumber<T extends @Nullable Number>(Class<T> targetType) implements Converter<Row, @Nullable T> {
@Override
public @Nullable T convert(Row source) {
public T convert(Row source) {
Object object = source.get(0);
@ -168,12 +169,12 @@ abstract class R2dbcConverters { @@ -168,12 +169,12 @@ abstract class R2dbcConverters {
*
* @author Hebert Coelho
*/
public enum RowToOffsetDateTimeConverter implements Converter<Row, OffsetDateTime> {
public enum RowToOffsetDateTimeConverter implements Converter<Row, @Nullable OffsetDateTime> {
INSTANCE;
@Override
public @Nullable OffsetDateTime convert(Row row) {
public OffsetDateTime convert(Row row) {
return row.get(0, OffsetDateTime.class);
}
}
@ -183,12 +184,12 @@ abstract class R2dbcConverters { @@ -183,12 +184,12 @@ abstract class R2dbcConverters {
*
* @author Hebert Coelho
*/
public enum RowToStringConverter implements Converter<Row, String> {
public enum RowToStringConverter implements Converter<Row, @Nullable String> {
INSTANCE;
@Override
public @Nullable String convert(Row row) {
public String convert(Row row) {
return row.get(0, String.class);
}
}
@ -198,12 +199,12 @@ abstract class R2dbcConverters { @@ -198,12 +199,12 @@ abstract class R2dbcConverters {
*
* @author Hebert Coelho
*/
public enum RowToUuidConverter implements Converter<Row, UUID> {
public enum RowToUuidConverter implements Converter<Row, @Nullable UUID> {
INSTANCE;
@Override
public @Nullable UUID convert(Row row) {
public UUID convert(Row row) {
return row.get(0, UUID.class);
}
}
@ -213,12 +214,12 @@ abstract class R2dbcConverters { @@ -213,12 +214,12 @@ abstract class R2dbcConverters {
*
* @author Hebert Coelho
*/
public enum RowToZonedDateTimeConverter implements Converter<Row, ZonedDateTime> {
public enum RowToZonedDateTimeConverter implements Converter<Row, @Nullable ZonedDateTime> {
INSTANCE;
@Override
public @Nullable ZonedDateTime convert(Row row) {
public ZonedDateTime convert(Row row) {
return row.get(0, ZonedDateTime.class);
}
}

5
spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/MySqlDialect.java

@ -80,12 +80,13 @@ public class MySqlDialect extends org.springframework.data.relational.core.diale @@ -80,12 +80,13 @@ public class MySqlDialect extends org.springframework.data.relational.core.diale
* @author Michael Berry
*/
@ReadingConverter
public enum ByteToBooleanConverter implements Converter<Byte, Boolean> {
@SuppressWarnings("NullAway")
public enum ByteToBooleanConverter implements Converter<Byte, @Nullable Boolean> {
INSTANCE;
@Override
public @Nullable Boolean convert(@Nullable Byte s) {
public Boolean convert(@Nullable Byte s) {
if (s == null) {
return null;

45
spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java

@ -352,9 +352,7 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @@ -352,9 +352,7 @@ public class MappingRelationalConverter extends AbstractRelationalConverter
if (getConversions().hasCustomReadTarget(RowDocument.class, rawType)) {
S converted = doConvert(documentAccessor.getDocument(), rawType, typeHint.getType());
Assert.state(converted != null, "Converted must not be null");
return converted;
}
@ -363,7 +361,10 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @@ -363,7 +361,10 @@ public class MappingRelationalConverter extends AbstractRelationalConverter
}
if (typeHint.isMap()) {
return context.convert(documentAccessor, typeHint);
S converted = context.convert(documentAccessor, typeHint);
Assert.state(converted != null, "Converted must not be null");
return converted;
}
RelationalPersistentEntity<?> entity = getMappingContext().getPersistentEntity(typeHint);
@ -425,7 +426,7 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @@ -425,7 +426,7 @@ public class MappingRelationalConverter extends AbstractRelationalConverter
* @param targetType the {@link Map} {@link TypeInformation} to be used to unmarshall this {@link RowDocument}.
* @return the converted {@link Collection} or array, will never be {@literal null}.
*/
protected @Nullable Object readCollectionOrArray(ConversionContext context, Collection<?> source,
protected Object readCollectionOrArray(ConversionContext context, Collection<?> source,
TypeInformation<?> targetType) {
Assert.notNull(targetType, "Target type must not be null");
@ -444,14 +445,14 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @@ -444,14 +445,14 @@ public class MappingRelationalConverter extends AbstractRelationalConverter
: CollectionFactory.createCollection(collectionType, rawComponentType, source.size());
if (source.isEmpty()) {
return getPotentiallyConvertedSimpleRead(items, targetType);
return getRequiredPotentiallyConvertedSimpleRead(items, targetType);
}
for (Object element : source) {
items.add(element != null ? context.convert(element, componentType) : element);
}
return getPotentiallyConvertedSimpleRead(items, targetType);
return getRequiredPotentiallyConvertedSimpleRead(items, targetType);
}
private <T> @Nullable T doConvert(Object value, Class<? extends T> target) {
@ -637,17 +638,17 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @@ -637,17 +638,17 @@ public class MappingRelationalConverter extends AbstractRelationalConverter
*
* @param value a value as it is returned by the driver accessing the persistence store. May be {@literal null}.
* @param targetType {@link TypeInformation} into which the value is to be converted. Must not be {@literal null}.
* @return The converted value. May be {@literal null}.
* @return the converted value, can be {@literal null}.
*/
@Override
@Nullable
public Object readValue(@Nullable Object value, TypeInformation<?> targetType) {
if (null == value) {
return null;
}
public @Nullable Object readValue(@Nullable Object value, TypeInformation<?> targetType) {
return null == value ? null : getPotentiallyConvertedSimpleRead(value, targetType);
}
return getPotentiallyConvertedSimpleRead(value, targetType);
private Object getRequiredPotentiallyConvertedSimpleRead(Object value, TypeInformation<?> type) {
Object result = getPotentiallyConvertedSimpleRead(value, type);
Assert.state(result != null, "Converted must not be null");
return result;
}
/**
@ -865,7 +866,7 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @@ -865,7 +866,7 @@ public class MappingRelationalConverter extends AbstractRelationalConverter
@SuppressWarnings("unchecked")
@Override
public <S> S convert(Object source, TypeInformation<? extends S> typeHint, ConversionContext context) {
public <S> @Nullable S convert(Object source, TypeInformation<? extends S> typeHint, ConversionContext context) {
Assert.notNull(source, "Source must not be null");
Assert.notNull(typeHint, "TypeInformation must not be null");
@ -875,7 +876,6 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @@ -875,7 +876,6 @@ public class MappingRelationalConverter extends AbstractRelationalConverter
}
if (source instanceof Collection<?> collection) {
if (typeHint.isCollectionLike() || typeHint.getType().isAssignableFrom(Collection.class)) {
return (S) collectionConverter.convert(context, collection, typeHint);
}
@ -1011,9 +1011,9 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @@ -1011,9 +1011,9 @@ public class MappingRelationalConverter extends AbstractRelationalConverter
*
* @param source must not be {@literal null}.
* @param typeHint must not be {@literal null}.
* @return the converted object.
* @return the converted object, can be {@literal null}.
*/
default <S> S convert(Object source, TypeInformation<? extends S> typeHint) {
default <S> @Nullable S convert(Object source, TypeInformation<? extends S> typeHint) {
return convert(source, typeHint, this);
}
@ -1023,9 +1023,9 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @@ -1023,9 +1023,9 @@ public class MappingRelationalConverter extends AbstractRelationalConverter
* @param source must not be {@literal null}.
* @param typeHint must not be {@literal null}.
* @param context must not be {@literal null}.
* @return the converted object.
* @return the converted object, can be {@literal null}.
*/
<S> S convert(Object source, TypeInformation<? extends S> typeHint, ConversionContext context);
<S> @Nullable S convert(Object source, TypeInformation<? extends S> typeHint, ConversionContext context);
/**
* Obtain a {@link ConversionContext} for the given property {@code name}.
@ -1186,9 +1186,8 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @@ -1186,9 +1186,8 @@ public class MappingRelationalConverter extends AbstractRelationalConverter
}
@Override
@Nullable
@SuppressWarnings("unchecked")
public <T> T getPropertyValue(RelationalPersistentProperty property) {
public <T> @Nullable T getPropertyValue(RelationalPersistentProperty property) {
String expression = property.getSpelExpression();
Object value = expression != null ? evaluator.evaluate(expression) : accessor.get(property);
@ -1353,7 +1352,7 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @@ -1353,7 +1352,7 @@ public class MappingRelationalConverter extends AbstractRelationalConverter
}
@Override
protected <T> T potentiallyConvertExpressionValue(Object object,
protected <T> @Nullable T potentiallyConvertExpressionValue(Object object,
Parameter<T, RelationalPersistentProperty> parameter) {
return context.convert(object, parameter.getType());
}

11
spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/TypedSubtreeVisitor.java

@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
*/
package org.springframework.data.relational.core.sql.render;
import java.util.Objects;
import java.util.function.Predicate;
import org.jspecify.annotations.Nullable;
@ -50,23 +51,19 @@ abstract class TypedSubtreeVisitor<T extends Visitable> extends DelegatingVisito @@ -50,23 +51,19 @@ abstract class TypedSubtreeVisitor<T extends Visitable> extends DelegatingVisito
private final ResolvableType type;
private @Nullable Visitable currentSegment;
enum Assignable {
YES, NO,
}
/**
* Creates a new {@link TypedSubtreeVisitor}.
*/
TypedSubtreeVisitor() {
this.type = refCache.computeIfAbsent(this.getClass(),
key -> ResolvableType.forClass(key).as(TypedSubtreeVisitor.class).getGeneric(0));
this.type = Objects.requireNonNull(refCache.computeIfAbsent(this.getClass(),
key -> ResolvableType.forClass(key).as(TypedSubtreeVisitor.class).getGeneric(0)));
}
/**
* Creates a new {@link TypedSubtreeVisitor} with an explicitly provided type.
*/
TypedSubtreeVisitor(Class<T> type) {
this.type = refCache.computeIfAbsent(type, key -> ResolvableType.forClass(type));
this.type = Objects.requireNonNull(refCache.computeIfAbsent(type, key -> ResolvableType.forClass(type)));
}
/**

Loading…
Cancel
Save