Возможно ли это: запрос JPA/Hibernate с результатом свойства list?
В спящем режиме я хочу запустить этот запрос 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 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)
Ответ 2
Я считаю, что вам нужно объявить конструктор 0-arg в вашем классе UserDTO
.
EDIT:
Или конструктор, который принимает Integer
вместо int
в качестве первого аргумента. При поиске конструкторов с использованием отражения Hibernate может не относиться к ним как к "совместимым" типам.
В принципе, я бы сосредоточился на части сообщения Unable to locate appropriate
constructor on class [...UserDTO]
.
Ответ 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