【发布时间】: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