Avoid warn logging for custom converters using Collection.
If the collection type is not a store-native type, we no longer issue a warn log. Converters can be registered for List or Collection types and convert into a different, non-collection type while being a support converter instead of forcing a specific write type. This is e.g. the case for MongoDB where a List of numbers is converted to the Vector type. Closes #3306
This commit is contained in:
@@ -70,7 +70,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
public class CustomConversions {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CustomConversions.class);
|
||||
private static Log logger = LogFactory.getLog(CustomConversions.class);
|
||||
private static final String READ_CONVERTER_NOT_SIMPLE = "Registering converter from %s to %s as reading converter although it doesn't convert from a store-supported type; You might want to check your annotation setup at the converter implementation";
|
||||
private static final String WRITE_CONVERTER_NOT_SIMPLE = "Registering converter from %s to %s as writing converter although it doesn't convert to a store-supported type; You might want to check your annotation setup at the converter implementation";
|
||||
private static final String NOT_A_CONVERTER = "Converter %s is neither a Spring Converter, GenericConverter or ConverterFactory";
|
||||
@@ -324,7 +324,8 @@ public class CustomConversions {
|
||||
|
||||
readingPairs.add(pair);
|
||||
|
||||
if (logger.isWarnEnabled() && !converterRegistration.isSimpleSourceType()) {
|
||||
if (logger.isWarnEnabled() && !converterRegistration.isSimpleSourceType()
|
||||
&& !Collection.class.isAssignableFrom(pair.getSourceType())) {
|
||||
logger.warn(String.format(READ_CONVERTER_NOT_SIMPLE, pair.getSourceType(), pair.getTargetType()));
|
||||
}
|
||||
}
|
||||
@@ -334,7 +335,8 @@ public class CustomConversions {
|
||||
writingPairs.add(pair);
|
||||
customSimpleTypes.add(pair.getSourceType());
|
||||
|
||||
if (logger.isWarnEnabled() && !converterRegistration.isSimpleTargetType()) {
|
||||
if (logger.isWarnEnabled() && !converterRegistration.isSimpleTargetType()
|
||||
&& !Collection.class.isAssignableFrom(pair.getTargetType())) {
|
||||
logger.warn(String.format(WRITE_CONVERTER_NOT_SIMPLE, pair.getSourceType(), pair.getTargetType()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,11 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.jmolecules.ddd.types.Association;
|
||||
import org.jmolecules.ddd.types.Identifier;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterFactory;
|
||||
@@ -44,6 +46,7 @@ import org.springframework.data.convert.Jsr310Converters.LocalDateTimeToDateConv
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link CustomConversions}.
|
||||
@@ -156,8 +159,7 @@ class CustomConversionsUnitTests {
|
||||
|
||||
var conversions = StoreConversions.of(new SimpleTypeHolder(Collections.singleton(Format.class), true));
|
||||
|
||||
var customConversions = new CustomConversions(conversions,
|
||||
Collections.singletonList(new FormatConverterFactory()));
|
||||
var customConversions = new CustomConversions(conversions, Collections.singletonList(new FormatConverterFactory()));
|
||||
|
||||
assertThat(customConversions.getCustomWriteTarget(String.class, SimpleDateFormat.class)).isPresent();
|
||||
}
|
||||
@@ -214,7 +216,7 @@ class CustomConversionsUnitTests {
|
||||
|
||||
new CustomConversions(StoreConversions.of(DATE_EXCLUDING_SIMPLE_TYPE_HOLDER),
|
||||
Collections.singletonList(Jsr310Converters.LocalDateTimeToInstantConverter.INSTANCE))
|
||||
.registerConvertersIn(registry);
|
||||
.registerConvertersIn(registry);
|
||||
|
||||
verify(registry).addConverter(any(Jsr310Converters.LocalDateTimeToInstantConverter.class));
|
||||
}
|
||||
@@ -293,8 +295,8 @@ class CustomConversionsUnitTests {
|
||||
@Test
|
||||
void hasValueConverterReturnsFalseWhenNoPropertyValueConversionsAreConfigured() {
|
||||
|
||||
ConverterConfiguration configuration = new ConverterConfiguration(StoreConversions.NONE,
|
||||
Collections.emptyList(), it -> true, null);
|
||||
ConverterConfiguration configuration = new ConverterConfiguration(StoreConversions.NONE, Collections.emptyList(),
|
||||
it -> true, null);
|
||||
|
||||
CustomConversions conversions = new CustomConversions(configuration);
|
||||
|
||||
@@ -315,8 +317,8 @@ class CustomConversionsUnitTests {
|
||||
|
||||
doReturn(true).when(mockPropertyValueConversions).hasValueConverter(eq(mockProperty));
|
||||
|
||||
ConverterConfiguration configuration = new ConverterConfiguration(StoreConversions.NONE,
|
||||
Collections.emptyList(), it -> true, mockPropertyValueConversions);
|
||||
ConverterConfiguration configuration = new ConverterConfiguration(StoreConversions.NONE, Collections.emptyList(),
|
||||
it -> true, mockPropertyValueConversions);
|
||||
|
||||
CustomConversions conversions = new CustomConversions(configuration);
|
||||
|
||||
@@ -328,6 +330,19 @@ class CustomConversionsUnitTests {
|
||||
verifyNoInteractions(mockProperty);
|
||||
}
|
||||
|
||||
@Test // GH-3306
|
||||
void doesNotWarnForAsymmetricListConverter() {
|
||||
|
||||
Log actualLogger = (Log) ReflectionTestUtils.getField(CustomConversions.class, "logger");
|
||||
Log actualLoggerSpy = spy(actualLogger);
|
||||
ReflectionTestUtils.setField(CustomConversions.class, "logger", actualLoggerSpy, Log.class);
|
||||
|
||||
new CustomConversions(StoreConversions.NONE, List.of(ListOfNumberToStringConverter.INSTANCE));
|
||||
|
||||
verify(actualLoggerSpy, never()).warn(anyString());
|
||||
verify(actualLoggerSpy, never()).warn(anyString(), any());
|
||||
}
|
||||
|
||||
private static Class<?> createProxyTypeFor(Class<?> type) {
|
||||
|
||||
var factory = new ProxyFactory();
|
||||
@@ -337,6 +352,16 @@ class CustomConversionsUnitTests {
|
||||
return factory.getProxy().getClass();
|
||||
}
|
||||
|
||||
@ReadingConverter
|
||||
enum ListOfNumberToStringConverter implements Converter<List<Number>, String> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
public String convert(List<Number> source) {
|
||||
return source.toString();
|
||||
}
|
||||
}
|
||||
|
||||
enum FormatToStringConverter implements Converter<Format, String> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
Reference in New Issue
Block a user