Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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();
    }
like image 610
Denis Rizov Avatar asked Oct 28 '13 06:10

Denis Rizov


2 Answers

You probably simply forgot to assign aliases to your projections:

Projections.projectionList()
           .add(Projections.property("id"), "id")
           .add(Projections.property("name"), "name")
like image 167
JB Nizet Avatar answered Oct 20 '22 20:10

JB Nizet


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.

like image 44
Thomas Champion Avatar answered Oct 20 '22 20:10

Thomas Champion