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 修复了它,上面的代码现在可以工作了