Spring Boot 2.3.x - 如何在自定义@RestController 中应用投影?
Spring Boot 2.3.x - How to apply a projection in a custom @RestController?
我正在尝试对从注释为@RestController 的自定义控制器返回的实体应用投影。
@RequestMapping(method = GET, value = "customer-api/students/viewProfile")
public @ResponseBody
ResponseEntity<?> fetchProfile(PersistentEntityResourceAssembler resourceAssembler) {
Student student = studentRepo.findByCreatedBy(accessToken.getSubject());
if (student != null) {
return new ResponseEntity<>(resourceAssembler.toModel(student), HttpStatus.OK);
} else {
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}
}
但是我得到了一个无限递归异常
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (WhosebugError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (WhosebugError) (through reference chain: org.springframework.data.jpa.mapping.JpaPersistentEntityImpl["idProperty"]->org.springframework.data.jpa.mapping.JpaPersistentPropertyImpl["owner"]->org.springframework.data.jpa.mapping.JpaPersistentEntityImpl["idProperty"]->org.springframework.data.jpa.mapping.JpaPersistentPropertyImpl["owner"]
此代码在 Spring Boot 1.5.17 中运行良好(我可以应用投影甚至格式化 HAL JSON)但它在 Spring 2.[=34= 中中断].
所以我本质上想要的是 Spring 数据 REST 导出控制器的功能,如投影和 HAL 格式 JSON。这可以在自定义控制器中执行吗?
我发现了一个类似的问题,但对我没有帮助。
编辑 1:
学生实体上没有双向关系。此外,我正在使用 PersistentEntityResourceAssembler
到 assemble 响应主体的 Student 实体,它将呈现任何 @ManyToOne 关联作为链接,正如 Oliver Gierke 在这个 中所解释的,所以我不确定如何递归可以
PersistentEntityResourceAssembler - which is usually injected into the
controller method. It renders a single entity in a Spring Data REST
way, which means that associations pointing to managed types will be
rendered as links etc.
既然你有一个 infinite recursion
问题,它只是意味着它正在序列化 parent 然后它的 child 然后 parent 的 child 然后又是 child ...你知道这是怎么回事吗? :)
你还没有发布你的 entities
所以我不能举一个相关的例子。但我会使用 @JsonManagedReference
-> Parent and @JsonBackReference
-> Child.
尝试用这两个来注释您的关系属性。为了使序列化工作,关系两侧的其中之一不应被序列化,以避免导致 Whosebug 错误的无限循环。
对于遇到相同问题的任何人,我通过升级到 Spring Boot 2.5.5 修复了它,上面的代码现在可以工作了
我正在尝试对从注释为@RestController 的自定义控制器返回的实体应用投影。
@RequestMapping(method = GET, value = "customer-api/students/viewProfile")
public @ResponseBody
ResponseEntity<?> fetchProfile(PersistentEntityResourceAssembler resourceAssembler) {
Student student = studentRepo.findByCreatedBy(accessToken.getSubject());
if (student != null) {
return new ResponseEntity<>(resourceAssembler.toModel(student), HttpStatus.OK);
} else {
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}
}
但是我得到了一个无限递归异常
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (WhosebugError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (WhosebugError) (through reference chain: org.springframework.data.jpa.mapping.JpaPersistentEntityImpl["idProperty"]->org.springframework.data.jpa.mapping.JpaPersistentPropertyImpl["owner"]->org.springframework.data.jpa.mapping.JpaPersistentEntityImpl["idProperty"]->org.springframework.data.jpa.mapping.JpaPersistentPropertyImpl["owner"]
此代码在 Spring Boot 1.5.17 中运行良好(我可以应用投影甚至格式化 HAL JSON)但它在 Spring 2.[=34= 中中断].
所以我本质上想要的是 Spring 数据 REST 导出控制器的功能,如投影和 HAL 格式 JSON。这可以在自定义控制器中执行吗?
我发现了一个类似的问题
编辑 1:
学生实体上没有双向关系。此外,我正在使用 PersistentEntityResourceAssembler
到 assemble 响应主体的 Student 实体,它将呈现任何 @ManyToOne 关联作为链接,正如 Oliver Gierke 在这个
PersistentEntityResourceAssembler - which is usually injected into the controller method. It renders a single entity in a Spring Data REST way, which means that associations pointing to managed types will be rendered as links etc.
既然你有一个 infinite recursion
问题,它只是意味着它正在序列化 parent 然后它的 child 然后 parent 的 child 然后又是 child ...你知道这是怎么回事吗? :)
你还没有发布你的 entities
所以我不能举一个相关的例子。但我会使用 @JsonManagedReference
-> Parent and @JsonBackReference
-> Child.
尝试用这两个来注释您的关系属性。为了使序列化工作,关系两侧的其中之一不应被序列化,以避免导致 Whosebug 错误的无限循环。
对于遇到相同问题的任何人,我通过升级到 Spring Boot 2.5.5 修复了它,上面的代码现在可以工作了