【问题标题】:Is SpringData's DomainClassConverter supposed to work with Hibernate proxies?SpringData 的 DomainClassConverter 是否应该与 Hibernate 代理一起使用?
【发布时间】:2018-04-29 08:33:33
【问题描述】:

我的团队维护着一个使用 Spring Boot、Spring Data、Thymeleaf 和 JPA/Hibernate 构建的 Web 应用。我们最近遇到了一个 Thymeleaf 模板 SpringEL 表达式由于类型转换问题而无法评估的问题:

原因:org.springframework.core.convert.ConverterNotFoundException:找不到能够从类型 [com.xyz.app.model.Employee_$$_jvst7ca_34] 转换为类型 [java.lang.String] 的转换器

表达式是 ${{employee}},其中employee 是一个由 Spring 控制器放入模型的实体。通过对 Spring Data 存储库的简单调用来检索员工实体:

@ModelAttribute("employee")
public Employee getEmployee(@PathVariable("employeeId") long employeeId) {
    return employeeRepository.findOne(employeeId);
}

在调试时,我注意到返回的 Employee 实体实际上是一个 Hibernate 代理,正如您在日志中的异常原因中看到的那样 - Employee 类具有 javassist 后缀:_$$_jvst7ca_34

Spring Data 使用 Spring 的 GenericConversionService 注册 DomainClassConverter,当 @EnableSpringDataWebSupport 注解存在时,它应该将实体转换为像 ${{employee}} 这样的表达式的 ID。 Spring Boot 提供了一个自动配置类SpringDataWebAutoConfiguration,它默认启用此功能。我确认我们的应用程序应用了这个自动配置类。

我还通过调试确认 GenericConversionService 在尝试从 Employee_$$_jvst7ca_34 转换为 String 时检索到 DomainClassConverter.ToIdConverter。但是 DomainClassConverter.ToIdConverter.matches(sourceType, targetType) 返回 false,因此不使用转换器。它返回 false,因为它在 Repositories 中找不到类型为 Employee_$$_jvst7ca_34 的存储库。我在调试器中看到存储库列表中唯一的员工存储库是用于Employee。

这是DomainClassConverter 中的错误吗?它不应该能够检索代理的存储库吗?似乎代理应该很常见,因为任何具有惰性集合(推荐的集合类型)的实体都会作为代理返回。还是我们做错了什么?任何提示将不胜感激!

【问题讨论】:

    标签: hibernate spring-boot spring-data thymeleaf


    【解决方案1】:

    原来这是 Spring Data Commons 中的一个错误。 issue 现已得到解决,在未来的版本中应该可以转换代理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-26
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 2018-12-24
      相关资源
      最近更新 更多