Execute “membro di” query 'ElementCollection' Mappa campi in JP-QL (JPA 2.0)
-
20-09-2019 - |
Domanda
E 'possibile eseguire un "membro di" query su array associativi? In caso affermativo, che cosa la sintassi simile? La soluzione ovvia è una query nativo ma che diventa piuttosto disordinato quello che con tutte le giunture e così via. Mi piacerebbe per verificare l'esistenza di un oggetto all'interno della mappa set, collezione valore o l'entrata set di chiavi. Forse qualcosa di simile al seguente:
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
Codice Provider-agnostico potrebbe essere troppo da chiedere; non EclipseLink supporta questa?
Soluzione
JPQL ha una funzione denominata index()
che è utile per ottenere l'indice in un elenco @OrderColumn
. E come hai detto tu stesso, le mappe sono anche chiamati array associativi e le chiavi della mappa corrispondono a indici degli array. Quindi nulla impedisce index()
di tornare la chiave di una voce di mappa.
Questa query funziona perfettamente su hibernate:
SELECT p FROM Person p, in (p.phoneNumbers) number
WHERE number = '867-5309' AND index(number) = 'home'
Altri suggerimenti
Dovrebbe funzionare:
SELECT p FROM Person p
WHERE (select count(*) from p.phoneNumbers where name='home' and value='867-5309') > 0
La prossima query funziona per me:
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'APP (2) specifica non definisce la sua sintassi di Mappa uso in MEMBRO (si stia riferendo in origine per gli array, ma non vedo la rilevanza se si dispone di una mappa) , di conseguenza, non si può fare affidamento su alcuna sintassi di essere valida per tutte le implementazioni JPA. Dal momento che JPQL non supporta metodi Java come keySet, valori quindi non riesco a vedere quelli che sono probabili. Più che probabile che supporta solo il controllo per un'esistenza valore, come
'867-5309' MEMBER OF p.phoneNumbers
Per riferimento, in JDOQL, si farebbe
p.phoneNumbers.containsKey('home');
p.phoneNumbers.containsValue('867-5309');