#305 - Consistently apply registered converters.
We now apply registered write converters to bindable values that are bound via bind(…) or provided through the Criteria/Update API.
This commit is contained in:
@@ -522,6 +522,20 @@ public class MappingR2dbcConverter extends BasicRelationalConverter implements R
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.r2dbc.convert.R2dbcConverter#getTargetType(Class)
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getTargetType(Class<?> valueType) {
|
||||
|
||||
Optional<Class<?>> writeTarget = getConversions().getCustomWriteTarget(valueType);
|
||||
|
||||
return writeTarget.orElseGet(() -> {
|
||||
return Enum.class.isAssignableFrom(valueType) ? String.class : valueType;
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------
|
||||
// Id handling
|
||||
// ----------------------------------
|
||||
|
||||
@@ -63,6 +63,15 @@ public interface R2dbcConverter
|
||||
*/
|
||||
Object getArrayValue(ArrayColumns arrayColumns, RelationalPersistentProperty property, Object value);
|
||||
|
||||
/**
|
||||
* Return the target type for a value considering registered converters.
|
||||
*
|
||||
* @param valueType must not be {@literal null}.
|
||||
* @return
|
||||
* @since 1.1
|
||||
*/
|
||||
Class<?> getTargetType(Class<?> valueType);
|
||||
|
||||
/**
|
||||
* Returns a {@link java.util.function.Function} that populates the id property of the {@code object} from a
|
||||
* {@link Row}.
|
||||
@@ -81,4 +90,5 @@ public interface R2dbcConverter
|
||||
* @return
|
||||
*/
|
||||
<R> R read(Class<R> type, Row source, RowMetadata metadata);
|
||||
|
||||
}
|
||||
|
||||
@@ -292,26 +292,29 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
return new DefaultGenericExecuteSpec(sqlSupplier);
|
||||
}
|
||||
|
||||
private static void bindByName(Statement statement, Map<String, SettableValue> byName) {
|
||||
private void bindByName(Statement statement, Map<String, SettableValue> byName) {
|
||||
|
||||
byName.forEach((name, o) -> {
|
||||
|
||||
if (o.getValue() != null) {
|
||||
statement.bind(name, o.getValue());
|
||||
SettableValue converted = dataAccessStrategy.getBindValue(o);
|
||||
if (converted.getValue() != null) {
|
||||
|
||||
statement.bind(name, converted.getValue());
|
||||
} else {
|
||||
statement.bindNull(name, o.getType());
|
||||
statement.bindNull(name, converted.getType());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void bindByIndex(Statement statement, Map<Integer, SettableValue> byIndex) {
|
||||
private void bindByIndex(Statement statement, Map<Integer, SettableValue> byIndex) {
|
||||
|
||||
byIndex.forEach((i, o) -> {
|
||||
|
||||
if (o.getValue() != null) {
|
||||
statement.bind(i, o.getValue());
|
||||
SettableValue converted = dataAccessStrategy.getBindValue(o);
|
||||
if (converted.getValue() != null) {
|
||||
statement.bind(i, converted.getValue());
|
||||
} else {
|
||||
statement.bindNull(i, o.getType());
|
||||
statement.bindNull(i, converted.getType());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -366,12 +369,12 @@ class DefaultDatabaseClient implements DatabaseClient, ConnectionAccessor {
|
||||
|
||||
if (byName.containsKey(name)) {
|
||||
remainderByName.remove(name);
|
||||
return byName.get(name);
|
||||
return dataAccessStrategy.getBindValue(byName.get(name));
|
||||
}
|
||||
|
||||
if (byIndex.containsKey(index)) {
|
||||
remainderByIndex.remove(index);
|
||||
return byIndex.get(index);
|
||||
return dataAccessStrategy.getBindValue(byIndex.get(index));
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -270,6 +270,15 @@ public class DefaultReactiveDataAccessStrategy implements ReactiveDataAccessStra
|
||||
actualType);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.r2dbc.function.ReactiveDataAccessStrategy#getBindValue(SettableValue)
|
||||
*/
|
||||
@Override
|
||||
public SettableValue getBindValue(SettableValue value) {
|
||||
return this.updateMapper.getBindValue(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.r2dbc.function.ReactiveDataAccessStrategy#getRowMapper(java.lang.Class)
|
||||
|
||||
@@ -58,6 +58,15 @@ public interface ReactiveDataAccessStrategy {
|
||||
*/
|
||||
OutboundRow getOutboundRow(Object object);
|
||||
|
||||
/**
|
||||
* Return a potentially converted {@link SettableValue} for strategies that support type conversion.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
* @since 1.1
|
||||
*/
|
||||
SettableValue getBindValue(SettableValue value);
|
||||
|
||||
/**
|
||||
* Returns a {@link BiFunction row mapping function} to map {@link Row rows} to {@code T}.
|
||||
*
|
||||
|
||||
@@ -252,6 +252,21 @@ public class QueryMapper {
|
||||
return createCondition(column, mappedValue, typeHint, bindings, criteria.getComparator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Potentially convert the {@link SettableValue}.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public SettableValue getBindValue(SettableValue value) {
|
||||
|
||||
if (value.isEmpty()) {
|
||||
return SettableValue.empty(converter.getTargetType(value.getType()));
|
||||
}
|
||||
|
||||
return SettableValue.from(convertValue(value.getValue(), ClassTypeInformation.OBJECT));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Object convertValue(@Nullable Object value, TypeInformation<?> typeInformation) {
|
||||
|
||||
@@ -264,13 +279,15 @@ public class QueryMapper {
|
||||
List<Object> mapped = new ArrayList<>();
|
||||
|
||||
for (Object o : (Iterable<?>) value) {
|
||||
mapped.add(this.converter.writeValue(o, typeInformation.getActualType()));
|
||||
mapped.add(convertValue(o, typeInformation.getActualType() != null ? typeInformation.getRequiredActualType()
|
||||
: ClassTypeInformation.OBJECT));
|
||||
}
|
||||
|
||||
return mapped;
|
||||
}
|
||||
|
||||
if (typeInformation.getType().isAssignableFrom(value.getClass())
|
||||
|| (typeInformation.getType().isArray() && value.getClass().isArray())) {
|
||||
if (value.getClass().isArray()
|
||||
&& (ClassTypeInformation.OBJECT.equals(typeInformation) || typeInformation.isCollectionLike())) {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user