Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用GROUPBY和having子句的JPA标准Api_Jpa_Jpa 2.0_Criteria Api - Fatal编程技术网

使用GROUPBY和having子句的JPA标准Api

使用GROUPBY和having子句的JPA标准Api,jpa,jpa-2.0,criteria-api,Jpa,Jpa 2.0,Criteria Api,我有一个实体,比如说设备,它有一个MAP类型的元素集合 class Device{ BigDecimal id; @ElementCollection MAP<String, String> properties; ...... } 经过两周的努力,我终于让它开始工作了。解决方案很简单,但在阅读了这里的JPA规范之后,终于想到了它 问题是groupBy中的column名称也应该在select子句中传递。在我的例子中,应该提到的是,即使设备是设备类的成员,JPA criteria

我有一个实体,比如说设备,它有一个MAP类型的元素集合

class Device{
BigDecimal id;
@ElementCollection
MAP<String, String> properties;
...... 
}

经过两周的努力,我终于让它开始工作了。解决方案很简单,但在阅读了这里的JPA规范之后,终于想到了它


问题是groupBy中的column名称也应该在select子句中传递。在我的例子中,应该提到的是,即使设备是设备类的成员,JPA criteria API也不会从设备中获取该ID。

如果您的JPA提供商在组中丢失了该ID,请向其提出错误。也许可以尝试在groupBy/have?之前设置where,即使在将where子句语句移到groupBy之上并具有相同的问题之后,也可以尝试设置where。假设这是EclipseLink(基于生成的SQL,但您仍然没有说使用了哪一个),所以请查看将其升级到最新版本或报告一个错误。
{
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])));
} 
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]]]