Выполнить запрос «MEMBER OF» для полей карты «ElementCollection» в JP-QL (JPA 2.0) - PullRequest
4 голосов
/ 10 октября 2009

Можно ли выполнить запрос "MEMBER OF" для ассоциативных массивов? Если да, то как выглядит синтаксис? Очевидный обходной путь - это собственный запрос, но он становится довольно беспорядочным со всеми соединениями и тому подобным. Я хотел бы проверить наличие объекта в наборе ключей карты, наборе значений или наборе записей. Может быть что-то вроде следующего:

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

Код, не зависящий от провайдера, может быть слишком большим для запроса; Eclipselink поддерживает это?

Ответы [ 3 ]

8 голосов
/ 27 августа 2011

JPQL имеет функцию с именем index(), которая полезна для получения индекса в списке @OrderColumn. И, как вы сказали сами, карты также называют ассоциативными массивами, а ключи карт соответствуют индексам массивов. Так что ничто не мешает index() вернуть ключ записи карты.

Этот запрос отлично работает в спящем режиме:

SELECT p FROM Person p, in (p.phoneNumbers) number 
WHERE number = '867-5309' AND index(number) = 'home'
4 голосов
/ 27 сентября 2012

Должно работать:

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

У меня работает следующий запрос:

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
1 голос
/ 10 октября 2009

Спецификация JPA (2) не определяет его синтаксис для Map использования в MEMBER OF (вы изначально ссылались на массивы, но я не вижу релевантности, если у вас есть карта) следовательно, вы не можете полагаться на любой синтаксис, действительный для всех реализаций JPA. Поскольку JPQL не поддерживает методы Java, такие как keySet, значения, то я не вижу вероятных. Скорее всего, он будет поддерживать только проверку существования значения, например

'867-5309' MEMBER OF p.phoneNumbers

Для справки, в JDOQL вы должны сделать

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