首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于接口投影的spring数据jpa -自定义类型转换

基于接口投影的spring数据jpa -自定义类型转换
EN

Stack Overflow用户
提问于 2019-10-16 15:47:01
回答 2查看 4.2K关注 0票数 8

我正在尝试实现界面投影,但无法使它与我的自定义类型列一起工作。

下面是我想要做的事情的例子:

储存库:

代码语言:javascript
复制
@Query(value = "SELECT customType from TABLE", nativeQuery = true)
List<TestClass> getResults();

界面投影:

代码语言:javascript
复制
public interface TestClass {
  @Convert(converter = MyCustomTypeConverter.class)
  MyCustomType getCustomType();
}

转换器:

代码语言:javascript
复制
@Converter
public class MyCustomTypeConverter implements Converter<String, MyCustomType> {

      @Override
      public MyCustomType convert(String source) {
        // whatever
      }
}

当我在存储库上调用getResults()时,我会收到预期的结果列表,但是当我试图对其中一个结果调用getCustomType()时,会得到异常:

代码语言:javascript
复制
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)

我发现问题在于

代码语言:javascript
复制
org.springframework.data.projection.ProxyProjectionFactory

它用

代码语言:javascript
复制
org.springframework.core.convert.support.DefaultConversionService

显然没有注册我的自定义类型转换器。

如果我在ConversionService中的断点停止,并在运行时手动添加我的转换器,则投影将没有任何问题。

所以问题是:我能否以某种方式将我的自定义转换器注册到spring在基于接口的投影中使用的ConversionService?

编辑:

我将我的转换器添加到InitializingBean中的DefaultConversionService的InitializingBean中,如下所示,它起了作用。

代码语言:javascript
复制
@Component
public class DefaultConversionServiceInitializer implements InitializingBean {

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

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-17 08:29:58

使用的ConversionServiceDefaultConversionService.getSharedInstance()

因此,您应该能够访问并添加您的转换器。

票数 3
EN

Stack Overflow用户

发布于 2021-12-07 00:22:49

这在SpringDataJPA2.4.0(参见这个封闭的GitHub问题)中再次中断。

用户ajobra76 (链接)建议的一个解决方法是指定转换器,如下所示:

代码语言:javascript
复制
public interface TestClass {
    @Value("#{@myCustomTypeConverter.convert(target.customType)}")
    MyCustomType getCustomType();
}

其中myCustomTypeConverter将是ApplicationContext中的一个bean。当然,还有其他使用SpEL指定方法的方法,包括创建new对象和调用静态方法。但这只是为了证明这是可以做到的。

target是一个标识符,它将绑定到“支持投影的聚合根”(Spring,节“公开投影”)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58417190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档