【发布时间】:2020-02-13 11:07:57
【问题描述】:
我正在尝试实现Interface-based Projection,但无法使其与我的自定义类型列一起使用。
下面是我正在尝试做的示例:
存储库:
@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 Converter<String, MyCustomType> {
@Override
public MyCustomType convert(String source) {
// 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 中的断点处停止并在运行时手动添加我的转换器,投影将毫无问题地工作。
所以问题是:我可以以某种方式将我的自定义转换器注册到 spring jpa 在基于接口的投影期间使用的 ConversionService 吗?
编辑:
我在 InitializingBean 中将我的转换器添加到 DefaultConversionService 的 sharedInstance 中,如下所示,它起作用了。
@Component
public class DefaultConversionServiceInitializer implements InitializingBean {
@Override
public void afterPropertiesSet() {
DefaultConversionService conversionService = (DefaultConversionService) DefaultConversionService.getSharedInstance();
conversionService.addConverter(new MyCustomTypeConverter());
}
}
【问题讨论】:
-
我有同样的问题,但这个解决方案不起作用。自定义转换器在上下文创建时添加到共享转换服务,但在解析 ProxyProjectionFactory 中的转换器时仍未找到。你用的是什么版本的spring-data?
-
弹簧靴 2.2.1.RELEASE。您是否在转换时检查 DefaultConversionService 是否包含您的转换器?我注意到 MyCustomTypeConverter 不是 AttributeConverter
而是 org.springframework.core.convert.converter.Converter 。也许这就是问题所在。我会更新我的问题。 -
要检查的另一件事是转换器的源类型是否符合您的预期。例如,在一种情况下,我必须使用源类型字符而不是字符串创建转换器。我会调试它并检查它尝试转换的确切类型
-
我在 2.0.4 spring boot 中遇到了这个问题,所以我想这是一个固定的问题。我尝试调试这个不透明的系统,并且在为我的存储库构建的动态代理中根本没有使用转换服务的共享实例。非常感谢您的反馈!进行更改的提交:github.com/spring-projects/spring-data-commons/commit/…
-
spring-boot 2.0.9 中引入了该问题的修复
标签: java spring-data-jpa projection converters nativequery