Code Setup

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
	Stream<User> streamAll();
}
@Service
@RequiredArgsConstructor
public class ToOutputStreamService {

	private final UserRepository userRepository;
	private final EntityManager entityManager;

	@Transactional(readOnly = true)
	public void writeToStream(final OutputStream os) throws IOException {
		entityManager.joinTransaction();
		final Stream<User> userStream = userRepository.streamAll();

		try (Writer writer = new BufferedWriter(new OutputStreamWriter(os))) {
			AtomicInteger counter = new AtomicCounter();
			userStream.forEach(user -> {
				try {
					writer.write(user.toString() + "\n");

					int i = counter.incrementAndGet();
					if (i % 100 == 0) {
						entityManager.flush();
						entityManager.clear(); // clear persistence context entity cache
					}
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			});
		}
	}
}
@RestContoller
@RequestMapping("/api")
@RequiredArgsContructor
public class ExampleController {

	private final ToOutputStreamService toOutputStreamService;

	@GetMapping("/download")
	public ResponseEntity<StreamingResponseBody> downloadFile() {
		StreamingResponseBody stream = os -> toOutputStreamService.writeToStream(os);
		return ResponseEntity.ok()
			.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=data.txt")
			.contentType(MediaType.APPLICATION_OCTET_STREAM)
			.body(stream);
	}
}
spring:
  mvc:
    async:
      request-timeout: 3600000 # increase timeout otherwise (only part of the file will be transferred to client)

Test

open the browser to http://localhost:8080/api/download