JPA 条件 Api 使用 group by 和 having 子句
JPA criteria Api using group by and having clause
我有一个实体可以说是具有 MAP 类型元素集合的设备
class Device{
BigDecimal id;
@ElementCollection
MAP<String, String> properties;
......
}
我需要编写查询来检索与一组给定属性匹配的所有设备。我使用标准 API.
编写了以下 JPA 查询
{
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Device> deviceQuery = criteriaBuilder.createQuery(Device.class);
Root<Device> device = deviceQuery.from(Device.class);
deviceQuery.select(device);
List<Predicate> criteria = new ArrayList<Predicate>();
if(!properties.isEmpty()){
MapJoin<Device, String, String > propertyJoin =device.joinMap("deviceProperties",JoinType.INNER);
Expression<BigDecimal> id = device.get(LocationConstants.ID);
for(Map.Entry<String,String> property : properties.entrySet()){
String key = property.getKey();
String value = property.getValue();
criteria.add(criteriaBuilder.and(criteriaBuilder.equal(propertyJoin.key(), key),
criteriaBuilder.equal(propertyJoin.value(), value)));
}
deviceQuery.groupBy(id);
deviceQuery.having(criteriaBuilder.equal(criteriaBuilder.count(id), properties.size()));
}
deviceQuery.where(criteriaBuilder.or(criteria.toArray(new Predicate[0])));
}
但此 returns 设备列表具有与提供给查询的任何输入属性子集匹配的重复值。
在查看形成的查询时,最终记录的查询中缺少 groupby 和 having 子句。知道为什么会这样,或者我在代码中犯了什么错误。谢谢 这里是最后的查询
SELECT t1.ID, t1.DEVICE_TYPE, t1.CREATEDBY, t1.CREATEDON, t1.DESCRIPTION, t1.MODIFIEDBY, t1.MODIFIEDON, t1.NAME, t1.ID1, t1.ID2, t1.ID3, t1.STATUS, t1.INSTANCE, t1.NAMESPACE, t1.URL, t1.MAJOR, t1.MINOR, t1."UID"
FROM LOC_DEVICE_PROPERTY t0, LOC_DEVICE t1
WHERE ((((((t0.PROPERTY_KEY = ?) AND (t0.PROPERTY_VALUE = ?))
OR ((t0.PROPERTY_KEY = ?) AND (t0.PROPERTY_VALUE = ?)))
OR ((t0.PROPERTY_KEY = ?) AND (t0.PROPERTY_VALUE = ?)))
OR ((t0.PROPERTY_KEY = ?) AND (t0.PROPERTY_VALUE = ?)))
AND (t0.Device_ID = t1.ID))
ORDER BY t1.ID ASC
[[bind => [8 parameters bound]]]
经过两周的努力,我终于让它工作了。解决方案很简单,但在阅读 JPA SPECIFICATION here 后终于想到了
http://download.oracle.com/otndocs/jcp/persistence-2_1-fr-eval-spec/index.html
问题是 groupBy 中的列名也应该在 select 子句中传递。在我的例子中应该提到 ID JPA 标准 API 不会从设备中获取它,即使设备是设备 class.
的成员
我有一个实体可以说是具有 MAP 类型元素集合的设备
class Device{
BigDecimal id;
@ElementCollection
MAP<String, String> properties;
......
}
我需要编写查询来检索与一组给定属性匹配的所有设备。我使用标准 API.
编写了以下 JPA 查询{
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Device> deviceQuery = criteriaBuilder.createQuery(Device.class);
Root<Device> device = deviceQuery.from(Device.class);
deviceQuery.select(device);
List<Predicate> criteria = new ArrayList<Predicate>();
if(!properties.isEmpty()){
MapJoin<Device, String, String > propertyJoin =device.joinMap("deviceProperties",JoinType.INNER);
Expression<BigDecimal> id = device.get(LocationConstants.ID);
for(Map.Entry<String,String> property : properties.entrySet()){
String key = property.getKey();
String value = property.getValue();
criteria.add(criteriaBuilder.and(criteriaBuilder.equal(propertyJoin.key(), key),
criteriaBuilder.equal(propertyJoin.value(), value)));
}
deviceQuery.groupBy(id);
deviceQuery.having(criteriaBuilder.equal(criteriaBuilder.count(id), properties.size()));
}
deviceQuery.where(criteriaBuilder.or(criteria.toArray(new Predicate[0])));
}
但此 returns 设备列表具有与提供给查询的任何输入属性子集匹配的重复值。 在查看形成的查询时,最终记录的查询中缺少 groupby 和 having 子句。知道为什么会这样,或者我在代码中犯了什么错误。谢谢 这里是最后的查询
SELECT t1.ID, t1.DEVICE_TYPE, t1.CREATEDBY, t1.CREATEDON, t1.DESCRIPTION, t1.MODIFIEDBY, t1.MODIFIEDON, t1.NAME, t1.ID1, t1.ID2, t1.ID3, t1.STATUS, t1.INSTANCE, t1.NAMESPACE, t1.URL, t1.MAJOR, t1.MINOR, t1."UID"
FROM LOC_DEVICE_PROPERTY t0, LOC_DEVICE t1
WHERE ((((((t0.PROPERTY_KEY = ?) AND (t0.PROPERTY_VALUE = ?))
OR ((t0.PROPERTY_KEY = ?) AND (t0.PROPERTY_VALUE = ?)))
OR ((t0.PROPERTY_KEY = ?) AND (t0.PROPERTY_VALUE = ?)))
OR ((t0.PROPERTY_KEY = ?) AND (t0.PROPERTY_VALUE = ?)))
AND (t0.Device_ID = t1.ID))
ORDER BY t1.ID ASC
[[bind => [8 parameters bound]]]
经过两周的努力,我终于让它工作了。解决方案很简单,但在阅读 JPA SPECIFICATION here 后终于想到了 http://download.oracle.com/otndocs/jcp/persistence-2_1-fr-eval-spec/index.html
问题是 groupBy 中的列名也应该在 select 子句中传递。在我的例子中应该提到 ID JPA 标准 API 不会从设备中获取它,即使设备是设备 class.
的成员