Spring Data JPA findAllById с идентификаторами 10K - PullRequest
0 голосов
/ 06 января 2020

У меня есть 10k идентификаторов, и мне нужно извлечь все записи из БД, но findAllById выдает stack overflow и не может завершить транзакцию.

Как мне решить эту проблему?

//itemsList has 10k records in csv format
List<Item> items = factory.getIemRepository().findAllById(itemsList);

Ответы [ 4 ]

1 голос
/ 06 января 2020

Исходя из вашей базы данных, большинство БД ограничивают количество идентификаторов, которые вы можете запросить одновременно. Предполагая, что 10k не превышает это ограничение для вашей конкретной базы данных, упомянутое вами stackoverflow наиболее вероятно, потому что вы возвращаете результаты 10k, а вашей системе не хватает памяти.

Попробуйте увеличить пространство кучи для Java. Например,

mvn spring-boot:run -Drun.jvmArguments="-Xmx1024m" -Drun.profiles=dev

Ссылка: Как настроить размер кучи при запуске приложения Spring Boot со встроенным Tomcat?

0 голосов
/ 07 января 2020

Сказать, что finaAllXXXX () не очень хороший способ. Мы должны либо выполнить более конкретный c запрос базы условий, либо использовать нумерацию страниц. Увеличение объема памяти не является решением, поскольку данные будут постепенно увеличиваться.

https://www.baeldung.com/spring-data-jpa-pagination-sorting

0 голосов
/ 06 января 2020

Вы можете создать метод с запросом WHERE id IN (:ids) в своем хранилище и вызвать его так:

private List getEdcsByEdcCodes(Collection<Long> idslist) {
    final int chunkSize = 500;
    final AtomicInteger counter = new AtomicInteger();

    Collection<Collection<Long>> devidedIdsList = edcCodes.stream()
        .collect(Collectors.groupingBy(resultList -> counter.getAndIncrement() / chunkSize))
        .values();

    return devidedIdsList.stream()
        .map(idsList -> findbyIdList(idsList))
        .flatMap(List::stream)
        .collect(Collectors.toList());
}
0 голосов
/ 06 января 2020

findAllById сгенерирует оператор SQL с предложением IN (т. Е. Где идентификатор в (val1, val2, ... val10000).

Это вызывает ошибку в Oracle (макс. 1000) и, возможно, другие БД. Если нет, он, вероятно, использует всю доступную память для хранения списка идентификаторов.

Есть несколько вариантов, но я бы рекомендовал сохранить идентификаторы 10k во временной таблице и выполнить SQL объединитесь с вашей основной таблицей. Это будет работать намного лучше, чем любая пакетная обработка или разбиение запроса в нескольких подзапросах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...