2010-04-20 20 views
12

在休眠我要運行該JPQL/HQL查詢:這是可能的:JPA/Hibernate查詢與結果中的列表屬性?

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個單獨的查詢嗎?

回答

10

沒有NEW查詢(選擇標值集合值路徑表達式),所以我不認爲加入NEW會讓事情的工作是無效的。

根據記錄,這是JPA 2.0規範中的部分4.8 SELECT子句說:

The SELECT clause has the following 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) 
+2

謝謝!我應該只是在JPA規範中查找它。顯然u.securityRoles不是'single_valued_pa​​th_expression'。所以我想這意味着,必須爲檢索集合/關係(或使用連接並使用循環創建集合)進行單獨的查詢。 – Kdeveloper 2010-04-20 22:09:22

+1

@Kdeveloper如果你的用戶有很多屬性,我想是的。如果沒有,只需選擇用戶並獲取他的安全角色即可。 – 2010-04-20 22:25:05

+0

@pascal thivent如果JPQL返回很多用戶,它最終將導致循環來檢索每個用戶權限的securityRoles? – HopeKing 2017-07-27 13:26:58

1

我相信你需要在你的UserDTO類中聲明一個0-參數的構造函數。

編輯: 或作爲第一個參數需要Integer而不是int的構造函數。當使用反射查找構造函數時,Hibernate可能不會將它們視爲「兼容」類型。

基本上,我會專注於消息的Unable to locate appropriate constructor on class [...UserDTO]部分。

+0

我同意,看起來Hibernate無法找到合適的構造函數。但爲什麼?如果我刪除了構造函數中的securityRoles並查詢代碼工作... – Kdeveloper 2010-04-20 21:38:10

+0

Integer中的int沒有什麼區別。零參數構造函數不是必需的,因爲HQL明確使用了命名構造函數(或者至少它通常) – Kdeveloper 2010-04-20 21:44:49

-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 
+0

你的建議不會編譯。 – Maciej 2013-08-21 19:13:27

相關問題