相同实体类型的双向多对多N + 1查询 [英] N+1 query on bidirectional many to many for same entity type

查看:77
本文介绍了相同实体类型的双向多对多N + 1查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下实体.我想从数据库中与所有她/他的朋友一起使用其原始类型字段(id,名称)来获得一个实体.在此示例中,它尝试返回所有朋友和朋友的朋友,因此创建了一个无限循环.我只想获取具有原始字段的第一级朋友对象.似乎是N + 1查询问题,但我找不到解决方案.是否有任何解决方案可以停止这种无限递归并返回我所提到的响应?

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

出现以下错误:

无法编写JSON:无限递归(StackOverflowError);

Could not write JSON: Infinite recursion (StackOverflowError);

但是我认为根本原因是N + 1查询,但 @EntityGraph @JsonBackReference 都无法解决我的问题.我不确定如何为相同类型的实体关系实现它们.

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:我对相同的代码有一个前提问题: 同一类型实体的多对多关系

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

推荐答案

尝试使用:

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

应该防止friends递归显示其friends.

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

这篇关于相同实体类型的双向多对多N + 1查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆