My Case
I have three entities: student
, subject
and teacher
which are structured as follows:
@Entity(name = "Student")
@Table(name = "Student")
public class Student
{
@Id
@Column(name = "id")
private String id;
@Column(name = "name")
private String name;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "student_id")
private List<Subject> subjectList = new ArrayList<Subject>();
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "student_id")
private List<Teacher> teacherList = new ArrayList<Teacher>();
}
@Entity(name = "Subject")
@Table(name = "Subject")
public class Subject
{
@Id
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "student_id")
private Student student;
}
@Entity(name = "Teacher")
@Table(name = "Teacher")
public class Teacher
{
@Id
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "student_id")
private Student student;
}
Student
id | name |
---|---|
A | Albert |
B | Jack |
Subject
id | name | student_id |
---|---|---|
1 | Math | A |
2 | History | B |
3 | Math | B |
4 | English | A |
Teacher
id | name | student_id |
---|---|---|
1 | Mr. H | B |
2 | Mr. E | B |
3 | Mr. L | A |
4 | Mr. P | A |
My Problem
I get two different results based on the type of method I try to get the results back, in fact neither of them is correct.
Method 1
StatelessSession session = getSession();
Student student = (Student) session.get(Student.class, "A");
In this case, the id, name and subjectList properties are returned to me correctly. But teacherList is empty!
Method 2
StatelessSession session = getSession();
Query<V> query = session.createNativeQuery("SELECT * FROM Student WHERE id = :id", Student.class);
List<V> list = query
.setParameter("id", "A")
.list();
In this second case, the object inside the list contains the properties: id, name and teacherList. But not subjetList, absurd!
How can I correctly return the "Student" object? What am I doing wrong?
CodePudding user response:
There are two issues:
- the mapping
- the stateless session
Remove the @JoinColumn
from Student
and use mappedBy
:
@Entity(name = "Student")
@Table(name = "Student")
public class Student
{
@Id
@Column(name = "id")
private String id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "student")
private List<Subject> subjectList = new ArrayList<Subject>();
@OneToMany(mappedBy = "student")
private List<Teacher> teacherList = new ArrayList<Teacher>();
}
You can find more examples about mapping bidirectional one-to-many in the documentation.
A stateless session has many limitations, in this case it would make more sense to use a regular Session
. This way lazy loading will work.
CodePudding user response:
Try changing FetchType
values from LAZY
to EAGER
. I think that's the problem. Since FetchType.LAZY
mode implies loading data on request. FetchType.EAGER
, in turn, loads the data with all the other fields