使用多列JPA2规范明确计数

时间:2018-01-10 12:38:21

标签: java oracle hibernate jpa exception

我正在尝试从我的Oracle数据库中找到一些结果,并且由于数据模型,我有重复的数据,我不想显示。

为了做到这一点,我认为在我的CriteriaQuery中使用DISTINCT应该可以解决问题。但在这里我遇到了问题:

必须在2列上进行distinct,这会使代码抛出以下异常:“ORA-00909:参数数量无效”。

经过一些谷歌搜索,发现使用这个东西:||将列分开工作,但我也没有一个线索可以做到这一点。

所以:

区分数据的正确方法如下:

SELECT DISTINCT column1, column2 FROM ...

但是Hibernate正在构建它:

SELECT DISTINCT COUNT( DISTINCT column1, column2) FROM

后一个查询是抛出异常的查询。有没有办法告诉Hibernate执行两个查询中的第一个?

提前致谢。

修改

涉及的代码是:

return new Specification<ProfilingInstructionAccessEntity>() {

        @Override
        public Predicate toPredicate(Root<ProfilingInstructionAccessEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            final List<Predicate> predicates = new ArrayList<>();
            List<FilterDTO> activeFilters = filtersService.findAllActive();

            filters.forEach((k, v) -> {
                if (!StringUtils.isBlank(v)) {
                    SpecificationHelperEnum helperEnum = SpecificationHelperEnum.getByKey(k);
                    SpecFilter filter = (SpecFilter) appContext.getBean(helperEnum.getFilter());
  //                        query.select(root.get("concated")).distinct(true); <-- This line is what I tried. Also tried this: query.distinct(true);
                    Predicate predicate = filter.createSmartPredicate(root, cb, v, helperEnum.getFilterId(), activeFilters);

                    predicates.add(predicate);
                }
            });
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        }
    };

@Override
public Predicate createSmartPredicate(Root<ProfilingInstructionAccessEntity> root, CriteriaBuilder cb, String value, Integer filterId, List<FilterDTO> activeFilters) {
    List<AssetDTO> assets = service.findBySpec("origin", value);
    List<Predicate> assetPredicates = new ArrayList<>();
    Join<Object, Object> aux = root.join(SearchPathEnum.ACCESS.getPath()).join(SearchPathEnum.ACCESS_FILTERS.getPath());
    for (AssetDTO assetDTO : assets) {
        List<Predicate> filterPredicates = new ArrayList<>();
        for (FilterDTO filterDTO : activeFilters) {
            filterPredicates.add(buildPredicate(assetDTO, filterDTO.getMappedValue(), aux, cb));
        }
        assetPredicates.add(cb.or(filterPredicates.toArray(new Predicate[filterPredicates.size()])));
    }
    return cb.or(assetPredicates.toArray(new Predicate[assetPredicates.size()]));
}

private Predicate buildPredicate(AssetDTO assetDTO, String mappedValue, Join<Object, Object> aux, CriteriaBuilder cb) {
    Predicate filterCode = cb.equal(aux.get(SearchPathEnum.FILTER.getPath()).get(SearchPathEnum.MAPPED_VALUE.getPath()), mappedValue);
    String value = (String) ReflectionComponent.invokeByReflection(assetDTO, "get" + StringUtils.capitalize(mappedValue), null);
    Predicate filterValue = cb.like(aux.get(SearchPathEnum.FILTER_VALUE.getPath()), "%" + value.trim() + "%");
    return cb.and(filterCode, filterValue);
}

这有点复杂,但最终它就像是“智能”搜索。我有20个过滤器,其中任何一个都会触发其他人的搜索。

如果需要更多信息,请随时提出要求。谢谢!

1 个答案:

答案 0 :(得分:0)

count(distinct column1, column2)无效。

实际上,这将是

select count(*)
from (select distinct column1, column2 from some_table);

我不知道 hibernate ,但是 - 上面发布的代码可能会响铃:)