15 Stimmen

Ist das möglich? JPA/Hibernate-Abfrage mit Listeneigenschaft im Ergebnis?

In Hibernate möchte ich diese JPQL / HQL-Abfrage ausführen:

select new org.test.userDTO( u.id, u.name, u.securityRoles)
FROM User u
WHERE u.name = :name

userDTO-Klasse:

public class UserDTO {
   private Integer id;
   private String name;
   private List<SecurityRole> securityRoles;

   public UserDTO(Integer id, String name, List<SecurityRole> securityRoles) {
     this.id = id;
     this.name = name;
     this.securityRoles = securityRoles;
   }

   ...getters and setters...
}

Benutzer-Entität:

@Entity
public class User {

  @id
  private Integer id;

  private String name;

  @ManyToMany
  @JoinTable(name = "user_has_role",
      joinColumns = { @JoinColumn(name = "user_id") },
      inverseJoinColumns = {@JoinColumn(name = "security_role_id") }
  )
  private List<SecurityRole> securityRoles;

  ...getters and setters...
}

Aber wenn Hibernate 3.5 (JPA 2) startet, erhalte ich diesen Fehler:

org.hibernate.hql.ast.QuerySyntaxException: Unable to locate appropriate 
constructor on class [org.test.UserDTO] [SELECT NEW org.test.UserDTO (u.id,
u.name, u.securityRoles) FROM nl.test.User u WHERE u.name = :name ]

Ist ein Select, der eine Liste (u.securityRoles) als Ergebnis enthält, nicht möglich? Sollte ich einfach 2 getrennte Abfragen erstellen?

11voto

Pascal Thivent Punkte 548176

Die Abfrage ohne das NEW (Auswahl eines Einzelwerts y ein sammlungswertiger Pfadausdruck) ist nicht gültig, daher glaube ich nicht, dass das Hinzufügen eines NEW wird die Dinge zum Laufen bringen.

In der JPA 2.0-Spezifikation heißt es dazu im Abschnitt 4.8 SELECT-Klausel :

Die SELECT-Klausel lautet wie folgt Syntax:

select_clause ::= SELECT [DISTINCT] select_item {, select_item}*
select_item ::= select_expression [ [AS] result_variable]
select_expression ::=
         single_valued_path_expression |
         scalar_expression |
         aggregate_expression |
         identification_variable |
         OBJECT(identification_variable) |
         constructor_expression
constructor_expression ::=
         NEW constructor_name ( constructor_item {, constructor_item}* )
constructor_item ::=
         single_valued_path_expression |
         scalar_expression |
         aggregate_expression |
         identification_variable
aggregate_expression ::=
         { AVG | MAX | MIN | SUM } ([DISTINCT] state_field_path_expression) |
         COUNT ([DISTINCT] identification_variable | state_field_path_expression |
                  single_valued_object_path_expression)

1voto

Grzegorz Oledzki Punkte 22253

Ich glaube, Sie müssen einen 0-Arg-Konstruktor in Ihrem UserDTO Klasse.

EDIT: Oder ein Konstruktor, der die Integer 代わりに int als erstes Argument. Bei der Suche nach Konstruktoren mit Reflection behandelt Hibernate sie möglicherweise nicht als "kompatible" Typen.

Im Wesentlichen würde ich mich auf die Unable to locate appropriate constructor on class [...UserDTO] Teil der Nachricht.

-2voto

SaSConsul Punkte 288

Ich denke, Sie sollten etwas wie dieses versuchen:

select new org.test.userDTO( u.id, u.name, u.securityRoles) AS uDTO,
  uDTO.setRoles(u.securityRoles)
 FROM User u
 WHERE u.name = :name

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X