2017-09-26 2 views
1

J'ai une entité appelée étudiantObtenir collections au sein d'une entité lors du mappage à DTO utilisant des transformateurs

@Entity 
@Table(name = "students") 
public class Student implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "STUDENT_ID") 
    private Integer studentId; 

    @Column(name = "STUDENT_NAME", nullable = false, length = 100) 
    private String studentName; 

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "student", cascade = CascadeType.ALL) 
    private List<Note> studentNotes; 

    // Some other instance variables that are not relevant to this question 

    /* Getters and Setters */ 

} 

et une entité appelée comme note

@Entity 
@Table(name = "notes") 
public class Note implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "NOTE_ID") 
    private Integer noteId; 

    @Column(name = "NOTE_CONTENT") 
    private String noteText; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "STUDENT_ID") 
    private Student student; 

    /* Getters and Setters */ 

} 

Comme vous pouvez le voir la relation dicte qu'un L'étudiant peut avoir plusieurs nombre de notes.

Pour afficher des informations sur l'élève sur une page particulière, je n'ai besoin que du nom de l'étudiant, du nombre de notes et de toutes les notes. J'ai créé un StudentDTO pour cela et il ressemble à ceci:

public class StudentDTO { 

    private Long count; 
    private String name; 
    private List<Note> notes; 

    /* Getters and setters */ 

} 

Et j'utilise le code suivant pour mapper l'étudiant et billets auprès de la DB à la StudentDTO

private static void testDTO() { 
     Session session = getSessionFactory().openSession(); 
     String queryString = "SELECT count(n) as count, s.studentName as name, s.studentNotes as notes " + 
       "from Student s join s.studentNotes n where s.id = 3"; 
     Query query = session.createQuery(queryString); 

     List<StudentDTO> list = query.setResultTransformer(Transformers.aliasToBean(StudentDTO.class)).list(); 
     for (StudentDTO u : list) { 
      System.out.println(u.getName()); 
      System.out.println(u.getCount()); 
      System.out.println(u.getNotes().size()); 
     } 
    } 

ci-dessus le code échoue quand il y a des notes récupérées dans la requête mais si j'enlève les notes et obtiens seulement le nom et compte cela fonctionne très bien.

Lorsque des notes est inclus dans la requête, c'est l'erreur qui est déclenché par Hibernate:

select 
      count(studentnot2_.NOTE_ID) as col_0_0_, 
      . as col_3_0_, 
      studentnot3_.NOTE_ID as NOTE_ID1_2_, 
      studentnot3_.NOTE_CONTENT as NOTE_CON2_2_, 
      studentnot3_.STUDENT_ID as STUDENT_3_2_ 
     from 
      students studentx0_ 
     inner join 
      notes studentnot2_ 
       on studentx0_.STUDENT_ID=studentnot2_.STUDENT_ID 
     inner join 
      notes studentnot3_ 
       on studentx0_.STUDENT_ID=studentnot3_.STUDENT_ID 
     where 
      studentx0_.STUDENT_ID=3; 

Et ceci est le message d'erreur que je reçois:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as col_3_0_, studentnot3_.NOTE_ID as NOTE_ID1_2_, studentnot3_.NOTE_CONTENT as N' at line 1 

Maintenant, je peux voir où la requête est fausse mais elle est générée par Hibernate, pas quelque chose que je contrôle. Y at-il quelque chose que j'ai besoin de changer dans ma chaîne de requête pour obtenir le résultat dont j'ai besoin.

Je ne veux pas mapper manuellement les résultats à mon DTO, est-il un moyen que je peux mappées directement mes studentNotes à Student.java aux notes dans StudentDTO.java

Répondre

0

On dirait que cette requête ne va pas. Le meilleur moyen est d'obtenir juste l'étudiant. Vous pouvez toujours obtenir la collection de notes d'un étudiant.

Session session = getSessionFactory().openSession(); 
String queryString = from Student s where s.studentId = 3; 
Query query = session.createQuery(queryString); 
Student student = query.getSingleResult(); 
sysout(student.getNotes().size()) 

De plus, je n'ai jamais récupéré la collection de cette manière dans la clause SELECT; donc, pas sûr mais avez-vous vraiment besoin

join s.studentNotes 

dans votre requête? Je ne sais pas si ma réponse est utile.

+0

Mais cela bat le but de DTO. Je vais devoir remplir manuellement les champs de StudentDTO –