'How to avoid json response recursiveness in parent-child jpa relationship?

I have this issue that I haven't reached to before so I am asking for some help. I have this entity class

@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder(toBuilder = true)
@Entity
@Table(name = "persons")
class Person {

       @Id
       @GeneratedValue(generator = "uuid")
       @GenericGenerator(name = "uuid", strategy = "uuid2")
       @Type(type = "uuid-char")
       private UUID id;

       @Column
       private String name;

       @Column
       private int age;

       @EqualsAndHashCode.Exclude
       @ToString.Exclude
       @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
       @JoinTable(name = "person_contact", joinColumns = {@JoinColumn(name = "person_id", referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name = "contact_id", referencedColumnName = "id")})
       private Set<Person> contacts;
}

The main issue that I have is that when I map this entity to a certain DTO which has the same properties shown above, when I am retrieving it from the controller side as a response, I get recursiveness because something is not right with the 'contacts' relationship. How can I get rid of this issue? I would only want to retrieve the id, age and name from the set not the set itself again and again. How can I ignore that?



Solution 1:[1]

I see 2 ways of "fixing" this issue:

  1. Just remove the Set<Person> property from the DTO.
  2. In case you use this property and only want to ignore it in the serialization to JSON, add a @JsonIgnore annotation to the field, and it wont get serialized in the response.

--EDIT According to the comment, you want to add this field, and have it show the data for the collection of Person but those should not have their "contacts" shown. You can create a second DTO class that has only the first 3 fields, and instead of adding a Set<Person> to the main DTO, add a Set<PersonContactDto> or similar.

Solution 2:[2]

Try this in your DTO:

@JsonIgnoreProperties({"contacts"})
private Set<PersonDto> contacts;

This will ignore the contacts field inside the set.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 YaatSuka