N+1 запрос на двунаправленный много-много для одного и того же типа объекта

У меня есть сущность, как показано ниже. Я хочу получить сущность из БД со всеми ее / его друзьями с их полями примитивного типа (id, name). В этом примере он пытается вернуть всех друзей и друзей друзей, поэтому создает бесконечный цикл. Я просто хочу получить объекты друзей первого уровня с примитивными полями. Это похоже на проблему с запросом N+1, но я не смог найти решение для нее. Есть ли решение для остановки этой бесконечной рекурсии и возврата ответа, как я уже упоминал?

@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;

Я создаю двунаправленную дружбу, как показано ниже:

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);
}

Это дает следующую ошибку:

Не удалось записать JSON: бесконечная рекурсия (StackruError);

Но я думаю, что основной причиной является N+1 запрос, но ни @EntityGraph, ни @JsonBackReference не стали решением для моего случая. Я не уверен, как реализовать их для однотипных отношений сущностей.

PS: у меня есть исходный вопрос об одном и том же коде: отношение " многие ко многим" для одного и того же типа объекта

1 ответ

Решение

Попробуй использовать:

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

Это должно предотвратить friends от показа их friends в рекурсии.

Другие вопросы по тегам