【问题标题】:Count distinct with multiple columns JPA2 specifications计数不同的多列 JPA2 规范
【发布时间】:2023-03-06 22:12:01
【问题描述】:

我正在尝试从我的 Oracle 数据库中查找一些结果,但由于数据模型的原因,我有重复的数据,我不想显示这些数据。

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

必须在 2 列上进行区分,这会使代码引发以下异常:“ORA-00909: invalid number of arguments”。

经过一番google搜索,发现使用了这个东西:||将列分开是可行的,但我也没有任何线索可以做到这一点。

所以:

区分我的数据的正确方法是这样的:

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 个过滤器,其中任何一个都会触发其他过滤器的搜索。

如果需要更多信息,请随时询问。谢谢!

【问题讨论】:

  • 使用原生查询怎么样?你能告诉我们你的代码吗?
  • 很抱歉,过了这么久才重新打开这个问题,但我们遇到了同样的问题。你还记得你是怎么修的吗?

标签: java oracle hibernate jpa exception


【解决方案1】:

在方言中注册新功能:

registerFunction("count_distinct", new SQLFunctionTemplate(IntegerType.INSTANCE, "count(distinct ?1)"));

并连接:

select count_distinct(column1 || column2) from some_table

【讨论】:

    【解决方案2】:

    count(distinct column1, column2) 无效。

    实际上是这样的

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

    我不知道 hibernate,但是 - 也许上面发布的代码会敲响你的钟声 :)

    【讨论】:

    • 问题是 Hibernate 自己做了不同的计数事情,我无法改变它(或者至少,我不知道如何)
    猜你喜欢
    • 2019-10-21
    • 2013-05-19
    • 2020-12-13
    • 2013-01-12
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    相关资源
    最近更新 更多