spring data jpa - Custom type conversion in interface-based projection

感情迁移 提交于 2019-12-24 03:51:34

问题


I'm trying to implement Interface-based Projection but I cannot make it work with my custom type column.

Below example of what I'm trying to do:

Repository:

@Query(value = "SELECT customType from TABLE", nativeQuery = true)
List<TestClass> getResults();

Interface projection:

public interface TestClass {
  @Convert(converter = MyCustomTypeConverter.class)
  MyCustomType getCustomType();
}

Converter:

@Converter
public class MyCustomTypeConverter implements AttributeConverter<MyCustomType, String> {

  @Override
  public String convertToDatabaseColumn(MyCustomType o) {
      // whatever;
  }

  @Override
  public MyCustomType convertToEntityAttribute(String value) {
      // whatever;
  }
}

When I call getResults() on repository I receive list of results as expected, but when I try to call getCustomType() on one of results I get exception:

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)

I found that problem lies in

org.springframework.data.projection.ProxyProjectionFactory

which uses

org.springframework.core.convert.support.DefaultConversionService

which obviously doesn't have my custom type converter registered.

If I stop on breakpoint in ConversionService and manually add my converter in runtime, projection will work without any problem.

So question is: can I somehow register my custom converter to ConversionService used by spring jpa during interface-based projection?

EDIT:

I added my converter to DefaultConversionService's sharedInstance in InitializingBean like below and it worked.

@Component
public class DefaultConversionServiceInitializer implements InitializingBean {

    @Override
    public void afterPropertiesSet() {
        DefaultConversionService conversionService = (DefaultConversionService) DefaultConversionService.getSharedInstance();
        conversionService.addConverter(new MyCustomTypeConverter());
    }
}

回答1:


The ConversionService used is DefaultConversionService.getSharedInstance().

So you should be able to access that and add your converter.



来源:https://stackoverflow.com/questions/58417190/spring-data-jpa-custom-type-conversion-in-interface-based-projection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!