Execute “MEMBER OF” query against 'ElementCollection' Map fields in JP-QL (JPA 2.0)

Deadly 提交于 2020-01-10 09:21:06

问题


Is it possible to run a "MEMBER OF" query against associative arrays? If so, what does the syntax look like? The obvious workaround is a native query but that gets pretty messy what with all the joins and such. I'd like to test for existence of an object within the map's key set, value collection or entry set. Maybe something like the following:

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-agnostic code might be too much to ask for; does Eclipselink support this?


回答1:


JPQL has a function named index() which is useful for getting the index in an @OrderColumn list. And as you said yourself, maps are also called associative arrays and map keys correspond to array indices. So nothing prevents index() from returning the key of a map entry.

This query works perfectly on hibernate:

SELECT p FROM Person p, in (p.phoneNumbers) number 
WHERE number = '867-5309' AND index(number) = 'home'



回答2:


It should work:

SELECT p FROM Person p 
WHERE (select count(*) from p.phoneNumbers where name='home' and value='867-5309') > 0

The next query works for 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



回答3:


The JPA(2) spec doesn't define its syntax for a Map use in MEMBER OF (you were referring originally to arrays but I don't see the relevance if you have a map), consequently you can't rely on any syntax being valid for all JPA implementations. Since JPQL doesn't support Java methods like keySet, values then I can't see those being likely. More than likely it will only support the check for a value existence, like

'867-5309' MEMBER OF p.phoneNumbers

For reference, in JDOQL, you would do

p.phoneNumbers.containsKey('home');
p.phoneNumbers.containsValue('867-5309');


来源:https://stackoverflow.com/questions/1548124/execute-member-of-query-against-elementcollection-map-fields-in-jp-ql-jpa-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!