这是可能的:结果中的list属性的JPA / Hibernate查询?

时间:2010-04-20 21:07:17

标签: hibernate jpa hql jpql jpa-2.0

在hibernate中我想运行这个JPQL / HQL查询:

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

userDTO类:

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

用户实体:

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

但是当Hibernate 3.5(JPA 2)启动时,我收到了这个错误:

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 ]

是否包含列表(u.securityRoles)的选项不可能?我应该创建两个单独的查询吗?

3 个答案:

答案 0 :(得分:10)

没有NEW的查询(选择标量值集合值路径表达式)无效,所以我不认为添加NEW会让事情奏效。

为了记录,这是JPA 2.0规范在 4.8 SELECT Clause 部分中所说的内容:

  

SELECT子句具有以下内容   语法:

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)

答案 1 :(得分:1)

我相信您需要在UserDTO类中声明一个0-arg构造函数。

编辑: 或者是以Integer而不是int作为第一个参数的构造函数。当使用反射查找构造函数时,Hibernate可能不会将它们视为“兼容”类型。

基本上,我会专注于消息的Unable to locate appropriate constructor on class [...UserDTO]部分。

答案 2 :(得分:-1)

我认为你应该尝试类似的事情:

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