简体   繁体   中英

Count distinct with multiple columns JPA2 specifications

I'm trying to find some results from my Oracle database and because of the data model, I have repeated data which I don't want to be shown.

In order to do this, I thought using DISTINCT in my CriteriaQuery should do the trick. But here I encountered the problem:

The distinct has to be made on 2 columns and this makes the code to throw the following exception: "ORA-00909: invalid number of arguments".

After some google search, found that using this things: || to separate the columns works, but I don't have a single clue to do this either.

So:

The correct way to distinct my data is like this:

SELECT DISTINCT column1, column2 FROM ...

But Hibernate is building it like this:

SELECT DISTINCT COUNT( DISTINCT column1, column2) FROM

The latter query is the one that throws the exception. Is there a way to tell Hibernate to do the first of the two queries?

Thanks in advance.

EDIT

The code involved is this:

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);
}

It's a bit complex but in the end it is something like a 'smart' search. I have like 20 filters and any single one of them trigger the search by the others.

If more information is needed please feel free to ask for it. Thanks!

count(distinct column1, column2) is invalid.

That would, actually, be

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

I don't know hibernate , but - maybe code posted above rings your bell :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM