0

I have an entity as below. I want to get an entity from DB with all of her/his friends with their primitive type fields (id, name). In this example, it is trying to return all friends and the friends of the friends so it is creating an infinite loop. I just want to get the first level friend objects with primitive fields. It seems like a N+1 query problem but I could not find a solution for it. Is there any solution for stopping this infinite recursion and returning the response as I mentioned?

@Builder
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "PERSON")
@ToString(exclude = "friends")
@EqualsAndHashCode(exclude = "friends")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Column(name = "name",unique = true)
    private String name;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "FRIENDSHIP",
           joinColumns = @JoinColumn(name = "person_id",  referencedColumnName = "id"),
           inverseJoinColumns = @JoinColumn(name = "friend_id",  referencedColumnName = "id"))
    private Set<Person> friends;

I am creating the bidirectional friendship as below:

public Person makeFriendship(String personName, String friendName) 
    throws FriendshipExistsException, PersonNotFoundException {
    Person person = retrieveWithName(personName);
    Person friend = retrieveWithName(friendName);
    if(!person.getFriends().contains(friend)){
        person.getFriends().add(friend);
        friend.getFriends().add(person);
        return repository.save(person);
} else {
    throw new FriendshipExistsException(personName, friendName);
}

It is giving the following error:

Could not write JSON: Infinite recursion (StackOverflowError);

But I think the root cause is N+1 query but neither @EntityGraph nor @JsonBackReference became a solution for my case. I am not sure how to implement them for same type entity relationships.

PS: I have a premise question about same code: Many to many relationship for same type entity

Cepr0
  • 28,144
  • 8
  • 75
  • 101
el nino
  • 129
  • 1
  • 3
  • 10

1 Answers1

2

Try to use:

@JsonIgnoreProperties("friends")
private Set<Person> friends;

It should prevent friends from the displaying of their friends in recursion.

Cepr0
  • 28,144
  • 8
  • 75
  • 101
  • Yes it is ignoring but it is also preventing to show root person’s friends list. I just want to return root element’s friend list but not the friends of friends. – el nino Feb 01 '18 at 13:50
  • Are you sure? Did you try to do this? – Cepr0 Feb 01 '18 at 13:52
  • 1
    @elnino I've modeled your situation now - all works as you need: it returns parents with their children but without grandchildren. – Cepr0 Feb 01 '18 at 15:11
  • Oh my bad! I tried `@JsonIgnore` instead of `@JsonIgnoreProperties`. Thanks mate. It works like a charm. :) – el nino Feb 01 '18 at 16:37