Execute „Mitglied von“ Abfrage 'ElementCollection' Map Felder in JP-QL (JPA 2.0)
-
20-09-2019 - |
Frage
Ist es möglich, ein „Mitglied“ Abfrage für assoziative Arrays laufen? Wenn ja, was tut die Syntax aussehen? Das offensichtliche Problem zu umgehen ist eine native Abfrage aber das wird ziemlich chaotisch, was mit alle verbinden und so. Ich würde die Existenz eines Objekts Test wie in der Karte des Schlüsselsatz, Werterfassung oder Eintragssatz. Vielleicht so etwas wie folgt aus:
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
Provider-unabhängiger Code könnte zu viel sein, um zu bitten; hat Eclipse unterstützt?
Lösung
JPQL hat eine Funktion namens index()
, die für das Erhalten des Index in einer @OrderColumn
Liste nützlich ist. Und wie Sie selbst gesagt, Karten sind auch assoziative Arrays und Kartenschlüssel entspricht Array-Indizes bezeichnet. Also nichts verhindert index()
den Schlüssel eines Map-Eintrags von der Rückkehr.
Diese Abfrage funktioniert perfekt auf Hibernate:
SELECT p FROM Person p, in (p.phoneNumbers) number
WHERE number = '867-5309' AND index(number) = 'home'
Andere Tipps
Es sollte funktionieren:
SELECT p FROM Person p
WHERE (select count(*) from p.phoneNumbers where name='home' and value='867-5309') > 0
Die nächste Abfrage funktioniert für mich:
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
Die PPV (2) Spezifikation definiert nicht die Syntax für eine Karte Verwendung in MEMBER OF (Sie bezogen sich ursprünglich auf Arrays, aber ich sehe nicht die Relevanz, wenn Sie eine Karte) folglich können Sie nicht auf einer Syntax verlassen für alle JPA-Implementierungen gültig. Da JPQL, keine Java-Methoden wie keySet unterstützen Werte dann kann ich nicht sehen, die wahrscheinlich zu sein. Mehr als wahrscheinlich wird es nur die Prüfung auf einen Wert Existenz unterstützen, wie
'867-5309' MEMBER OF p.phoneNumbers
Als Referenz in JDOQL, würden Sie tun,
p.phoneNumbers.containsKey('home');
p.phoneNumbers.containsValue('867-5309');