许多对同一类型实体的关系 [英] Many to many relationship for same type entity

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

问题描述

我有一个实体,如下所示。我很好奇,如果可以创建一个关系,我将用这个例子来描述:


  • 我正在创建2个 Person 实体 Michael Julia

  • 我将Julia添加到Michael的好友套装中。 b
  • 之后,我将Michael作为JSON响应进行检索,并在响应中提供Julia。但是当我找回朱莉娅的时候,她的朋友组是空的。我想通过拯救友谊的一方来创造双向的友谊关系。我想让迈克尔在Julia的朋友身上做任何其他的操作。我认为它必须由Hibernate管理。

      @ToString(exclude =friends)//编辑:这2个排除

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @列(name =id)
    私人长ID;

    @Column(name =name,unique = true)
    私有字符串名称;

    @JsonIgnoreProperties(friends)//编辑:将阻止无限递归
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name =FRIENDSHIP,
    joinColumns = @JoinColumn(name =person_id,
    referencedColumnName =id),
    inverseJoinColumns = @JoinColumn(name =friend_id,
    referencedColumnName =id ))
    private Set< Person>朋友;




这是我的服务层代码,友谊:

  @Override 
public Person addFriend(String personName,String friendName)
throws FriendshipExistsException,PersonNotFoundException {
Person person = retrieveWithName(personName);
Person friend = retrieveWithName(friendName);
if(!person.getFriends()。contains(friend)){
person.getFriends()。add(friend);
return repository.save(person);
}
else {
抛出new FriendshipExistsException(personName,friendName);


$ / code $ / pre

lockquote

相关问题:
N + 1查询双向许多到许多相同的实体类型



更新了源代码并且此版本正常工作。



解决方案

  //创建图形以帮助hibernate创建带外连接的查询。 
@NamedEntityGraph(name =graph.Person.friends,
attributeNodes = @NamedAttributeNode(value =friends))
class Person {}

interface PersonRepository扩展了JpaRepository< Person,Long> {
//使用指定的图表,它将在同一查询中获取所有朋友
@Override
@EntityGraph(value =graph.Person.friends)
Person findOne长ID);

$ b @Override
public Person addFriend(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); //只使用一种保存方法,它可以节省级联
}的朋友其他{
抛出新的FriendshipExistsException(personName,friendName);
}

}

如果你检查你的hibernate日志,你会看到:

Hibernate:insert into person(name,id)values(?,?)

Hibernate:insert into person(name,id)values(?,?)

Hibernate:插入友情(person_id,friend_id)values(?,?)

Hibernate:插入友谊(person_id,friend_id)值(?,?)


I have an entity as below. I am curious if it is possible to create a relationship as I will be describing with the example:

  • I am creating 2 Person entities Michael and Julia.
  • I am adding Julia to Michael's friends set.
  • After that I am retrieving Michael as a JSON response and Julia is available in the response. But when I am retrieving Julia, her friends set is empty. I want to create the bidirectional friendship relation by saving just one side of the friendship. I would like to get Michael on Julia's friends set without doing any other operations. I think that it must be managed by Hibernate. Is it possible and how should I do it?

    @ToString(exclude = "friends") // EDIT: these 2 exclusion necessary
    @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;
    
    @JsonIgnoreProperties("friends") // EDIT: will prevent the infinite recursion
    @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;
    

Here is my service layer code for creating a friendship:

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

Related Question: N+1 query on bidirectional many to many for same entity type

Updated the source code and this version is working properly.

解决方案

// Creating a graph to help hibernate to create a query with outer join.
@NamedEntityGraph(name="graph.Person.friends",
    attributeNodes = @NamedAttributeNode(value = "friends"))
class Person {}

interface PersonRepository extends JpaRepository<Person, Long> {
    // using the named graph, it will fetch all friends in same query
    @Override
    @EntityGraph(value="graph.Person.friends")
    Person findOne(Long id);
}

@Override
public Person addFriend(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); // need to setup the relation
        return repository.save(person); // only one save method is used, it saves friends with cascade
    } else {
        throw new FriendshipExistsException(personName, friendName);
    }

}

If you check your hibernate logs, you will see:
Hibernate: insert into person (name, id) values (?, ?)
Hibernate: insert into person (name, id) values (?, ?)
Hibernate: insert into friendship (person_id, friend_id) values (?, ?)
Hibernate: insert into friendship (person_id, friend_id) values (?, ?)

这篇关于许多对同一类型实体的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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