2013-10-28 76 views
12

我是Hibernate的新手,我試圖從數據庫中獲取一些數據。我不想獲得完整的數據,而只是一個實體的投影。Java - Hibernate criteria.setResultTransformer()使用默認值初始化模型字段

問題是,在for循環中,當我得到id和我的投影的名稱時,它獲取默認值id = 0和name = null而不是id = 7和name =「Name 8」是數據庫中原始實體的記錄。你知道是什麼原因導致這個問題? for循環處於最後一個代碼中。

這裏是學生實體

@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 
} 

這裏是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; 
    } 
} 

而且我執行

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(); 
    } 

回答

21

代碼你可能只是忘了別名分配給您的預測:

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

當屬性具有相同的名稱時,爲什麼我們必須指定別名? – Ram

+0

你救了我的命!謝謝 – Erez

4

除了和迴應@Ram評論:

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

「id」和「名」在你的學生級的Java字段名,但在數據庫中它們被命名爲「StudentId」和「名稱「,而且hibernate使用隨機別名生成SQL查詢以避免名稱衝突,所以在結果集中沒有」id「和」name「列。 上述示例中的第二個參數強制使用別名。

Hibernate來生成SQL這樣的:

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

您可以告訴Hibernate通過Hibernate的配置文件hibernate.cfg.xml設置hibernate.show_sql爲true,以顯示在控制檯/日誌中生成的SQL查詢。