2013-10-28 25 views
12

Jestem nowy w Hibernate i próbuję uzyskać pewne dane z bazy danych. Nie chcę uzyskać pełnych danych, ale projekcję podmiotu.Java - Hibernate criteria.setResultTransformer() inicjuje pola modelu z wartościami domyślnymi

Chodzi o to, że w pętli for kiedy otrzymam identyfikator i nazwę mojej projekcji, otrzymuje ona wartości domyślne id = 0 i name = null zamiast id = 7 i name = "Name 8" which są zapisy oryginalnego obiektu w bazie danych. Czy wiesz, co powoduje ten problem? Pętla for jest w ostatnim kodzie.

Oto Student Podmiot

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

Oto 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; 
    } 
} 

I kod mam wykonywania

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

Odpowiedz

21

Prawdopodobnie po prostu zapomniał przypisać aliasy do projekcji :

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

Kiedy właściwości mają tę samą nazwę, dlaczego musimy podać aliasy? – Ram

+0

Uratowałeś mi życie !!! Dzięki – Erez

4

Dodatkowo i odpowiedzieć na @Ram komentarz:

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

„id” oraz „name” Java nazwa pola w klasie Student, lecz w bazie danych są nazwane „StudentId” i " Name ", ponadto hibernacja generuje zapytanie SQL z losowym aliasem, aby uniknąć konfliktu nazw, dlatego w zestawie wyników nie ma kolumny" id "i" nazwa ". Drugi parametr w powyższym przykładzie wymusza nazwę aliasu.

Hibernate wygenerowania SQL tak:

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

Można powiedzieć hibernacji, aby wyświetlić wygenerowane zapytanie SQL w konsoli/log ustawiając hibernate.show_sql true w pliku konfiguracyjnym Hibernate hibernate.cfg.xml.