Reputation: 10531
The schema is here: http://sqlfiddle.com/#!9/5ec63/2
or here; Query from many-to-many relationship
Now, I created the following classes:
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;
}
}
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;
}
}
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.
Upvotes: 1
Views: 1674
Reputation: 19956
You need only one entity 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;
}
}
Upvotes: 1
Reputation: 516
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:
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.
Upvotes: 2