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
в рекурсии.