2010-04-20 4 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: Entity

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 ВЫБРАТЬ пункта:

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_path_expression». Поэтому я предполагаю, что это означает, что нужно делать отдельные запросы для извлечения коллекций/отношений (или использовать объединение и создавать коллекции с циклом). – Kdeveloper

+1

@Kdeveloper Если у вас есть много атрибутов, я так думаю. Если нет, просто выберите пользователя и выберите его securityRoles. –

+0

@pascal thivent И если JPQL возвращает много пользователей, это в конечном итоге приведет к циклу для получения прав безопасности каждого пользователя? – HopeKing

1

Я считаю, что вам нужно объявить конструктор 0-arg в классе UserDTO.

EDIT: Или конструктор, который принимает Integer вместо int в качестве первого аргумента. При поиске конструкторов с использованием отражения Hibernate может не относиться к ним как к «совместимым» типам.

В принципе, я хотел бы сосредоточиться на части сообщения Unable to locate appropriate constructor on class [...UserDTO].

+0

Я согласен, кажется, что Hibernate не может найти подходящего конструктора. Но почему? Если я удалю securityRoles как в contructor, так и в запросе кода работает ... – Kdeveloper

+0

int to Integer, не имеет значения. Конструктор нулевого аргумента не нужен, потому что HQL явно использует именованный конструктор (или, по крайней мере, он обычно) – Kdeveloper

-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

 Смежные вопросы

  • Нет связанных вопросов^_^