这可能吗:JPA/Hibernate query with list property in result?
Posted
技术标签:
【中文标题】这可能吗:JPA/Hibernate query with list property in result?【英文标题】:Is this possible: JPA/Hibernate query with list property in result? 【发布时间】:2011-02-10 08:10:41 【问题描述】:在休眠中我想运行这个 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) 的结果?我应该只创建 2 个单独的查询吗?
【问题讨论】:
【参考方案1】:没有NEW
的查询(选择标量值和 集合值路径表达式)无效,所以我认为添加NEW
不会使事情正常进行.
作为记录,这是 JPA 2.0 规范在 4.8 SELECT 子句部分中所说的:
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)
【讨论】:
谢谢!我应该在 JPA 规范中查找它。显然 u.securityRoles 不是“single_valued_path_expression”。所以我想这意味着,必须单独查询来检索集合/关系(或使用连接并使用循环创建集合)。 @Kdeveloper 如果您的用户有很多很多属性,我猜是这样。如果没有,只需选择用户并获取他的 securityRoles。 @pascal thivent 如果 JPQL 返回很多用户,最终会导致一个循环来检索每个用户的 securityRoles 对吗?【参考方案2】:我相信您需要在 UserDTO
类中声明一个 0-arg 构造函数。
编辑:
或者一个以Integer
而不是int
作为第一个参数的构造函数。在使用反射查找构造函数时,Hibernate 可能不会将它们视为“兼容”类型。
基本上,我会关注消息的Unable to locate appropriate
constructor on class [...UserDTO]
部分。
【讨论】:
我同意,Hibernate 似乎找不到合适的构造函数。但为什么?如果我删除了构造函数中的 securityRoles 并查询代码是否有效... int 到 Integer,没有任何区别。不需要零参数构造函数,因为 HQL 显式使用命名构造函数(或至少它正常使用)【参考方案3】:我认为您应该尝试以下方法:
select new org.test.userDTO( u.id, u.name, u.securityRoles) AS uDTO,
uDTO.setRoles(u.securityRoles)
FROM User u
WHERE u.name = :name
【讨论】:
你的建议没有通过。以上是关于这可能吗:JPA/Hibernate query with list property in result?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Jpa Hibernate Query 中将数字数组作为参数传递? [关闭]
“插入忽略”或“重复键更新”使用 @Query 和 @Modifying 而不使用 nativeQuery 或 save() 或 saveAndFlush() JPA Hibernate
如何将 LocalDateTime 提供给 jpa/hibernate 查询?