简体   繁体   中英

Modeling many-to-many Relationship in JPA/Hibernate

The schema is here: http://sqlfiddle.com/#!9/5ec63/2

or here; Query from many-to-many relationship

Now, I created the following classes:

  1. Student.java

     @Entity public class Student implements Serializable { @Id @GeneratedValue private int id; @NotNull @Size(min = 1, max = 35) private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } 
  2. Friend.java

     @Entity public class Friend implements Serializable { @EmbeddedId @NotNull @ManyToMany( targetEntity = Student.class ) private FriendPK primaryKey; public FriendPK getPrimaryKey() { return primaryKey; } public void setPrimaryKey(FriendPK primaryKey) { this.primaryKey = primaryKey; } } 
  3. FriendPK.java

     @Embeddable public class FriendPK implements Serializable { @JoinColumn( name = "id_from", referencedColumnName = "id") private int idFrom; @JoinColumn( name = "id_to", referencedColumnName = "id") private int idTo; public FriendPK() { } public int getIdFrom() { return idFrom; } public void setIdFrom(int idFrom) { this.idFrom = idFrom; } public int getIdTo() { return idTo; } public void setIdTo(int idTo) { this.idTo = idTo; } } 

1) Is this enough to model the many-to-many relationship? More specifically,

2) Do I need another "List friends" variable in Student class to store this student's friends?

3) Likewise, do I need another "List students" variable in Friend class to store students which are friends?

I vaguely feel the current design isn't enough, but can't figure out exactly what's needed.

Thank you.

Usually, to implement a many to many relation you need to use some middle table to map keys from two other tables.

In your case you need, say, t_students_friends table with two columns like the following:

t_students_friends

student_pk | friend_pk

In your entity classes you may need Lists for students and/or friends. Note that @ManyToMany also requires a @JoinTable annotation to work. If you want to access friends of a student, add to your Student class:

@ManyToMany
@JoinTable(
  name="t_students_friends",
  joinColumns=@JoinColumn(name="student_pk", referencedColumnName="id"),
  inverseJoinColumns=@JoinColumn(name="friend_pk", referencedColumnName="id"))
private List<Friend> friends;

You should also modify Friend class as follows. Add

@ManyToMany(mappedBy="friends")
private List<Student> students;

and use simple @Id int id field as you do in Students. There is no need in a FriendsPK class.

For more information you can read here , for example.

You need only one persistent to implement such schema. Hibernate will create a join table for @ManyToMany association. If you need to specify name of the join table you can use a @JoinTable annotation.

You don't need the Friend class. You can deal with friends with HQL or Criteria . So you don't need to know about a join table. Hibernate will add joins for a join table while converting HQL to SQL .

from Student s inner join fetch s.friends where s.name = :studentName

Keep in mind that it is HQL , for JPQL you need select .

@Table
@Entity
public class Student {

    @Id
    @GeneratedValue
    private int id;

    @NotNull
    @Size(min = 1, max = 35)        
    private String name;

    @ManyToMany
    private List<Student> friends = new ArrayList<Student>();

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Student> getFriends() {
        return friends;
    }

    public void setFriends(List<Student> friends) {
        this.friends = friends;
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM