在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)的选项不可能?我应该创建两个单独的查询吗?
答案 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