Exécuter « MEMBRE » requête contre les champs de la carte « ElementCollection » dans JP-QL (JPA 2.0)
-
20-09-2019 - |
Question
Est-il possible d'exécuter un « membre de » requête sur les tableaux associatifs? Si oui, à quoi ressemble la syntaxe comme? La solution évidente est une requête native mais qui est assez compliqué ce avec toutes les jointures et autres. Je voudrais tester l'existence d'un objet dans jeu de clés, collection de valeur ou un ensemble d'entrée de la carte. Peut-être quelque chose comme ce qui suit:
SELECT p FROM Person p WHERE 'home' MEMBER OF p.phoneNumbers.keySet
SELECT p FROM Person p WHERE '867-5309' MEMBER OF p.phoneNumbers.values
SELECT p FROM Person p WHERE {'home' -> '867-5309'} MEMBER OF p.phoneNumbers
Code fournisseur agnostique peut-être trop demander; ne EclipseLink supporte cela?
La solution
JPQL a une fonction nommée index()
qui est utile pour obtenir l'index dans une liste de @OrderColumn
. Et comme vous l'avez dit, les cartes sont également appelés tableaux associatifs et les clés de carte correspondent aux indices de tableau. Donc, rien n'empêche index()
de retourner la clé d'une entrée de la carte.
Cette requête fonctionne parfaitement sur Mise en veille prolongée:
SELECT p FROM Person p, in (p.phoneNumbers) number
WHERE number = '867-5309' AND index(number) = 'home'
Autres conseils
Il devrait fonctionner:
SELECT p FROM Person p
WHERE (select count(*) from p.phoneNumbers where name='home' and value='867-5309') > 0
La prochaine requête fonctionne pour moi:
select model from AnsOutboxMsg model
left join fetch model.updateEntity upde
left join fetch upde.update upd
left join fetch model.ansMessage msg
left join fetch msg.template msgt
left join fetch msg.ansAction act
left join fetch act.ansRule rl
left join fetch rl.app app
where (select count(*) from model.contextMap where name = 'fltClient' and value = 'XXX') > 0 and model.status = 'sent' and app.id = 'SPN_TICKETS' and msgt.name = 'Client' order by model.modifDate DESC, model.id ASC
L'Assemblée parlementaire paritaire (2) spécification ne définit pas sa syntaxe pour Carte utiliser dans MEMBRE (vous faisiez référence à l'origine à des tableaux, mais je ne vois pas la pertinence si vous avez une carte) , vous pouvez par conséquent pas compter sur une syntaxe étant valable pour toutes les implémentations JPA. Étant donné que JPQL ne supporte pas les méthodes Java comme keySet, les valeurs que je ne peut donc pas voir ceux-ci étant probable. Plus que probablement, il ne soutiendra que le chèque pour une existence de valeur, comme
'867-5309' MEMBER OF p.phoneNumbers
Pour référence, JDOQL, vous feriez
p.phoneNumbers.containsKey('home');
p.phoneNumbers.containsValue('867-5309');