Home > Blockchain >  I get different results from the "same query" in Hibernate
I get different results from the "same query" in Hibernate

Time:06-16

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

  • Related