2017-09-14 4 views
0

Est-il possible (et si oui comment) de créer une requête de critères qui aboutit à un tuple ou un tableau dont certains éléments sont des collections d'une propriété de collection évaluée?Requête de critère contenant une propriété de valeur de collection

Compte tenu d'une entité Dummy qui a un List<SubEntities> avec le nom subs

class Dummy { 
    String name; 
    List<SubEntity> subs; 
} 

class SubEntity { 
    // some attributes 
} 

Je veux une requête API de critères qui se traduit par quelque chose avec la structure

Tuple>

Un Array au lieu d'un Tuple serait bien, même pour un Array ou similaire pour List.

J'ai essayé les éléments suivants:

CriteriaBuilder cb = em.getCriteriaBuilder(); 

CriteriaQuery<Object[]> q = cb.createQuery(Object[].class); 
Root<DummyEntityWithCollection> root = q.from(DummyEntityWithCollection.class); 
Join<Object, Object> subs = root.join("subs"); 
q.select(cb.array(root.get("name"), subs)); 

List<Object[]> list = em.createQuery(q).getResultList(); 

Mais les Object[] s contenus dans list ont le deuxième élément SubEntity s au lieu de List<SubEntity>.

Celui-ci échoue de la même manière:

CriteriaBuilder cb = em.getCriteriaBuilder(); 

CriteriaQuery<Tuple> q = cb.createTupleQuery(); 
Root<DummyEntityWithCollection> root = q.from(DummyEntityWithCollection.class); 
Join<Object, Object> subs = root.join("subs"); 
q.multiselect(root.get("name"), subs); 

List<Tuple> list = em.createQuery(q).getResultList(); 

Cette variante

CriteriaBuilder cb = em.getCriteriaBuilder(); 

CriteriaQuery<Object[]> q = cb.createQuery(Object[].class); 
Root<DummyEntityWithCollection> root = q.from(DummyEntityWithCollection.class); 
q.select(cb.array(root.get("name"), root.get("subs"))); 

List<Object[]> list = em.createQuery(q).getResultList(); 

ne fonctionne pas du tout et les résultats dans une instruction SQL non valide avec une seule . comme une colonne de sélection (au moins pour Hibernate et HSQLDB).

La question How can I retrieve a collection property using criteria Api semble indiquer que ce n'est pas possible mais elle est basée sur Hibernate et je voudrais obtenir une réponse basée sur JPA. En particulier, une réponse indiquant la section de la spécification de l'APP qui précise que cela n'est pas possible serait appréciée.

Répondre

1

JPQL defines la clause select dans la section 4.8 comme

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 

de sorte que vous pouvez voir que les expressions à plusieurs valeurs ne sont pas sélectionnables dans JPQL. Les critères sont simplement un moyen de créer une requête à l'aide d'une API et d'objets.

Voir le chapitre 6.1 JPA spec:

La sémantique des critères les requêtes sont conçues pour refléter celles de Java Persistence requête requêtes en langage.

Il est donc raisonnable de supposer que la même contrainte s'applique à l'API Criteria.

+1

Merci pour les pointeurs. J'ai ajouté quelques références explicites et un lien. –