Всем привет, такой вопрос. Есть список который может содержать более 1000 элементов, по которому надо сделать сравнение. Oracle не позволяет добавить в один 'in' более 1000 элементов, по этому хочу через цикл разбить один большой запрос на несколько поменьше. Для этого использую следующий метод (в коде ограничено числом 3 чтобы локально воспроизвести, в h2 лежит меньше сущностей):
public Page<DivisionView> getDivisions(Pageable pageable, String q, Long macroRegionId) {
User loggedUser = userRepository.findOne(idEquals(SecurityContextUtils.getLoggedUserId()));
Set<Long> shopIds = shopRepository.findAll(shopService.specificationByRole(loggedUser)).stream().map(Shop::getId).collect(Collectors.toSet());
Specification<OrgStructureDivision> specification = null;
Specification<OrgStructureDivision> shopSpecification = null;
Set<Long> thousandIds = new HashSet<>();
for (Long id: shopIds) {
if (thousandIds.size() < 3) {
thousandIds.add(id);
} else {
shopSpecification = divisionSpecificationForThousandIds(shopSpecification, thousandIds);
thousandIds.clear();
}
}
shopSpecification = divisionSpecificationForThousandIds(shopSpecification, thousandIds);
specification = where(specification).and(shopSpecification);
return repository.findAll(specification, pageable).map(DivisionView::buildFromEntity);
}
private Specification<OrgStructureDivision> divisionSpecificationForThousandIds(Specification<OrgStructureDivision> shopSpecification, Set<Long> thousandIds) {
return shopSpecification == null
? shopIn(thousandIds)
: where(shopSpecification).or(shopIn(thousandIds));
}
Есть спецификация:
public static Specification<OrgStructureDivision> shopIn(Set<Long> shopIds) {
return (root, criteriaQuery, cb) -> {
criteriaQuery.distinct(true);
Join<OrgStructureCluster, Shop> shopJoin = root.join(OrgStructureDivision_.clusters).join(OrgStructureCluster_.shops);
return shopJoin.in(shopIds);
};
}
на выходе получается что то вроде:
select distinct orgstructu0_.division_id as division1_41_,
orgstructu0_.external_id as external2_41_,
orgstructu0_.external_system as external3_41_,
orgstructu0_.active as active4_41_,
orgstructu0_.guid as guid5_41_,
orgstructu0_.macro_region_id as macro_re7_41_,
orgstructu0_.name as name6_41_
from structure_division orgstructu0_
inner join structure_cluster clusters1_ on orgstructu0_.division_id = clusters1_.division_id
inner join shop shops2_ on clusters1_.id = shops2_.cluster_id
inner join structure_cluster clusters3_ on orgstructu0_.division_id = clusters3_.division_id
inner join shop shops4_ on clusters3_.id = shops4_.cluster_id
where (shops4_.id in (5) or shops2_.id in (5));
Проблема в том что в списке приходит (-2, 1, 2, 4, 5) а в спецификации всё обрубается и несколько раз по in (5) проверяет. Подскажите пожалуйста с чем это может быть связано?
Я не уверен но в вашем варианте два раза вызов есть в цикле и потом без цикла
divisionSpecificationForThousandIds
Как вариант сделать временную таблицу и запихнуть туда все id. А потом сделать
your_sql WHERE some_id IN ( SELECT some_id FROM some_tmp_table )
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
В таблице Location содержится информация которая должна выбираться согласно связи charactersorigin_id reference to location
При первом запуске Android Studio возникает окно, с помощью которого можно установить все необходимые расширения, но после создания первого проекта,...
Пытаюсь сделать кластеризацию в приложении с использованием библиотеки mapbox и их плагина аннотацийВ разрабатываемом приложении необходимо...
Пожалуйста помогите решить эту проблему, хотя бы в какую сторону копать решение