Я пытаюсь реализовать Проецирование на основе интерфейса , но я не могу заставить его работать с моим столбцом пользовательского типа.
Ниже приведен пример того, что я пытаюсь сделать:
Репозиторий:
@Query(value = "SELECT customType from TABLE", nativeQuery = true)
List<TestClass> getResults();
Проекция интерфейса:
public interface TestClass {
@Convert(converter = MyCustomTypeConverter.class)
MyCustomType getCustomType();
}
Конвертер:
@Converter
public class MyCustomTypeConverter implements AttributeConverter<MyCustomType, String> {
@Override
public String convertToDatabaseColumn(MyCustomType o) {
// whatever;
}
@Override
public MyCustomType convertToEntityAttribute(String value) {
// whatever;
}
}
Когда я вызываю getResults () в репозитории, я получаю списокрезультаты, как и ожидалось, но когда я пытаюсь вызвать getCustomType () для одного из результатов, я получаю исключение:
java.lang.IllegalArgumentException: Projection type must be an interface!
at org.springframework.util.Assert.isTrue(Assert.java:118)
at org.springframework.data.projection.ProxyProjectionFactory.createProjection(ProxyProjectionFactory.java:100)
at org.springframework.data.projection.SpelAwareProxyProjectionFactory.createProjection(SpelAwareProxyProjectionFactory.java:45)
at org.springframework.data.projection.ProjectingMethodInterceptor.getProjection(ProjectingMethodInterceptor.java:131)
at org.springframework.data.projection.ProjectingMethodInterceptor.invoke(ProjectingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.ProxyProjectionFactory$TargetAwareMethodInterceptor.invoke(ProxyProjectionFactory.java:245)
Я обнаружил, что проблема заключается в
org.springframework.data.projection.ProxyProjectionFactory
, который использует
org.springframework.core.convert.support.DefaultConversionService
, в котором явно не зарегистрирован мой пользовательский конвертер типов.
Если я остановлюсь на точке останова в ConversionService и вручную добавлю конвертер во время выполнения, проекция будет работать без проблем.
Итак, вопрос: могу ли я каким-то образом зарегистрировать свой собственный конвертер в ConversionService, используемый Spring jpa во время проекции на основе интерфейса?
РЕДАКТИРОВАТЬ:
Я добавил свой конвертер вDefaultConversionService's sharedInstanceв InitializingBean, как показано ниже, и это сработало.
@Component
public class DefaultConversionServiceInitializer implements InitializingBean {
@Override
public void afterPropertiesSet() {
DefaultConversionService conversionService = (DefaultConversionService) DefaultConversionService.getSharedInstance();
conversionService.addConverter(new MyCustomTypeConverter());
}
}