Ответ
Stream, возвращаемый JPA-репозиторием (например, через метод, помеченный @Query), привязан к активным ресурсам базы данных. Его необходимо закрывать для:
- Освобождения соединения с БД: Stream может удерживать JDBC-соединение из пула.
- Закрытия курсора: При ленивой потоковой обработке больших результатов СУБД открывает курсор, который потребляет память на стороне сервера БД.
Незакрытый Stream приводит к утечкам ресурсов, исчерпанию пула соединений и потенциальной блокировке операций.
Правильный подход с try-with-resources:
try (Stream<Employee> employeeStream =
employeeRepository.streamAllByDepartment("Engineering")) {
// Обработка в памяти
List<String> names = employeeStream
.map(Employee::getName)
.collect(Collectors.toList());
} // Stream, а вместе с ним курсор и соединение, будут закрыты здесь автоматически
Важно: Работа со Stream в JPA обычно должна выполняться в пределах активной транзакции (@Transactional), так как для загрузки каждой следующей записи может потребоваться доступ к БД.