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();
}
You probably simply forgot to assign aliases to your projections:
Projections.projectionList()
.add(Projections.property("id"), "id")
.add(Projections.property("name"), "name")
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
.
来源:https://stackoverflow.com/questions/19628759/java-hibernate-criteria-setresulttransformer-initializes-model-fields-with-d