0

I am trying to apply projection on an entity returned from a custom controller annotated @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);
    }

}

But I am getting an infinite recursion exception

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (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"]

This code works fine in Spring Boot 1.5.17 (I can apply projections and even get HAL formatted JSON) but it breaks in Spring 2.3.x.

So what I essentially want is the functionality of a Spring Data REST exported controller like projections and HAL formatted JSON. Is that possible to do in a custom controller?

I found a similar question here but it didnt help me.

Edit 1:

There is no bi-directional relationship on Student entity. Also I am using the PersistentEntityResourceAssembler to assemble the Student entity for response body which will render any @ManyToOne association as links as explained by Oliver Gierke in this answer so I am not sure how recursion is possible

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.

Charlie
  • 3,113
  • 3
  • 38
  • 60
  • The fields "idProperty" and "owner" clearly have circular dependency and Renis1235 soultion is right – Arun Sai Mustyala Oct 13 '21 at 07:33
  • Well there are no fields by that name in `Student` entity. So I am thinking it is an issue with the `PersistentEntityResourceAssembler` – Charlie Oct 13 '21 at 07:36

2 Answers2

2

Since you have an infinite recursion problem, it simply means that it is serializing the parent then its child and then the parent of the child and then the child again... Do you see where this is going? :)

You have not posted your entities so I cannot take a relevant example. But I would use @JsonManagedReference -> Parent and @JsonBackReference -> Child.

Try annotating your Relationship Attributes with these two. For the serialization to work, one of the two sides of the relationship should not be serialized, in order to avoid the infinite loop that causes your StackOverflow error.

Renis1235
  • 4,116
  • 3
  • 15
  • 27
  • Well the `Student` entity doesnt have any bi-directional relationship. Also in Spring Boot 1.5.17 if the entity has a a child which is a refrence type it is simply added to json output as a link and will not be serialized in order to prevent recursions like this. – Charlie Oct 13 '21 at 06:38
  • 1
    But we are talking about spring boot 2.3.x now right? Can you please post the relevant part of your entity? – Renis1235 Oct 13 '21 at 06:55
  • I cannot post the entity for company policy reasons. Even in Spring Boot 2.3.x the serialization is the same for Spring Data REST generated controllers. I am just trying recreate the same functionality – Charlie Oct 13 '21 at 07:09
  • I just upgraded the Spring Boot version to 2.5.5 and the code above now works – Charlie Oct 14 '21 at 05:42
  • Do you mean with the `@Json` annotations or just as it was before? – Renis1235 Oct 14 '21 at 08:02
  • It was as before. No changes in code. – Charlie Oct 14 '21 at 08:04
  • Glad that your issue was resolved :) – Renis1235 Oct 14 '21 at 08:21
0

For anyone having the same issue, I fixed it by upgrading to Spring Boot 2.5.5 and the code above now works

Charlie
  • 3,113
  • 3
  • 38
  • 60