Java - Hibernate criteria.setResultTransformer() initializes model fields with default values
Asked Answered
R

2

13

I am new to Hibernate and I am trying to get some data from the database. I don't want to get the full data but a projection of an entity.

The thing is that in the for-loop when I get the id and the name of my projection, it gets the default values id=0 and name=null instead of id=7 and name="Name 8" which are the records of the original entity in the database. Do you know what causes this problem? The for-loop is in the last code.

Here is the Student Entity

@Entity(name = "Students")
public class Student {
    @Id
    @GeneratedValue
    @Column(name = "StudentId")
    private int id;

    @Column(name = "Name", nullable = false, length = 50)
    private String name;

    @Column(name = "Grade")
    private Double grade = null;

    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "FacultyId", nullable = false)
    private Faculty faculty;

    @ManyToMany(cascade = CascadeType.PERSIST)
    @JoinTable(
        joinColumns = @JoinColumn(name = "StudentId"),
        inverseJoinColumns = @JoinColumn(name = "CourseId"))
    private Collection<Course> courses;

    public Student() {
        this.courses = new HashSet<Course>();
    }

    // Setters and Getters for all fields
}

Here is the StudentModel

public class StudentModel {
    private  int id;
    private String name;

    public int getId() {
        return this.id;
    }

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

    public String getName() {
        return this.name;
    }

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

And the code I am executing

Session session = sessionFactory.openSession();
    session.beginTransaction();
    {
        Criteria criteria = session.createCriteria(Student.class);
        criteria.add(Restrictions.eq("name", "Name 8"))
                .setProjection(
                        Projections.projectionList()
                                .add(Projections.property("id"))
                                .add(Projections.property("name")))
                .setResultTransformer(
                        Transformers.aliasToBean(StudentModel.class));

        @SuppressWarnings("unchecked")
        List<StudentModel> students = criteria.list();

        for (StudentModel student : students) {
            System.out.println(student.getId());
            System.out.println(student.getName());
        }

        session.getTransaction().commit();
        session.close();
    }
Resolved answered 28/10, 2013 at 6:58 Comment(0)
E
22

You probably simply forgot to assign aliases to your projections:

Projections.projectionList()
           .add(Projections.property("id"), "id")
           .add(Projections.property("name"), "name")
Everest answered 28/10, 2013 at 8:14 Comment(1)
When the properties have the same name, why do we have to specify the aliases?Riella
T
4

In addition and to respond to @Ram comment :

Projections.projectionList()
       .add(Projections.property("id"), "id")
       .add(Projections.property("name"), "name")

"id" and "name" are Java field name in your Student class, but in your database they are named "StudentId" and "Name", moreover hibernate generate SQL query with random alias to avoid name conflict, so in result set there are not "id" and "name" column. The second parameter in the above example force the alias name.

Hibernate generate SQL like that :

SELECT students0_.StudientId as StudientId12, students0_.Name as Name34, students0_.Grade as Grade11 FROM Students students0_

You can tell hibernate to display generated SQL query in console/log by setting hibernate.show_sql to true in Hibernate config file hibernate.cfg.xml.

Tawny answered 20/11, 2015 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.