对于相同的实体类型,N + 1查询双向多对多

时间:2018-02-01 12:00:47

标签: java hibernate many-to-many spring-data-jpa

我有一个实体如下。我想从DB中获取一个实体,其所有的朋友都有他们的原始类型字段(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:无限递归(StackOverflowError);

但我认为根本原因是N + 1查询,但 @EntityGraph @JsonBackReference 都不能成为我案例的解决方案。我不确定如何为相同类型的实体关系实现它们。

  

PS:我有一个关于相同代码的前提问题:   Many to many relationship for same type entity

1 个答案:

答案 0 :(得分:2)

尝试使用:

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

它应该阻止friends在递归中显示friends