对JP-QL(JPA 2.0)中的'ElementCollection'映射字段执行“MEMBER OF”查询

时间:2009-10-10 14:39:11

标签: java orm jpa eclipselink jpql

是否可以针对关联数组运行“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 个答案:

答案 0 :(得分:8)

JPQL有一个名为index()的函数,它对于在@OrderColumn列表中获取索引很有用。正如你自己所说,地图也称为关联数组,地图键对应于数组索引。因此,没有什么能阻止index()返回地图条目的键。

此查询在hibernate上完美运行:

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

答案 1 :(得分:4)

应该有效:

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

答案 2 :(得分:1)

JPA(2)规范没有定义其在MEMBER OF中使用 Map 的语法(你最初指的是数组,但如果你有地图,我看不到相关性)因此,您不能依赖任何对所有JPA实现有效的语法。由于JPQL不支持像keySet这样的Java方法,因此我无法看到那些可能的值。它很可能只支持检查价值存在,比如

'867-5309' MEMBER OF p.phoneNumbers

作为参考,在JDOQL中,你可以

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