Skip to content

Provide repository fragment for streaming #2273

Closed
@quaff

Description

@quaff

It's necessary to stream data for batch processing, Spring Data JPA supports return Stream type, but it must be called in @Transactional methods, and sometimes it failed even @Transactional presented, for example:

	@Transactional(readOnly = true)
	public ResponseEntity<StreamingResponseBody> download(@SortDefault(sort = "id") Sort sort) {
		return ResponseEntity.ok(outputStream -> {
			try (Stream<User> all = userRepository.findBy(sort)) {
				// write user to outputStream
			}
		});
	}

I fixed it by adding a default method to repository:

	Stream<User> streamAllBy(Sort sort);

	@Transactional(readOnly = true)
	default void forEach(Sort sort, Consumer<User> consumer) {
		// avoid org.springframework.dao.InvalidDataAccessApiUsageException
		// see JpaQueryExecution.StreamExecution::doExecute
		try (Stream<T> all = streamAllBy(sort)) {
			all.forEach(consumer);
		}
	}
	public ResponseEntity<StreamingResponseBody> download(@SortDefault(sort = "id") Sort sort) {
		return ResponseEntity.ok(outputStream -> {
				userRepository.forEach(sort, user -> {
					// write user to outputStream
				});
		});
	}

I hope Spring Data JPA can provide a repository fragment such as:

import java.util.function.Consumer;
import java.util.stream.Stream;

import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;

public interface StreamingRepository<T> {

	Stream<T> streamAllBy(Sort sort);

	@Transactional(readOnly = true)
	default void forEach(Consumer<T> consumer) {
		forEach(Sort.unsorted(), consumer);
	}

	@Transactional(readOnly = true)
	default void forEach(Sort sort, Consumer<T> consumer) {
		try (Stream<T> all = streamAllBy(sort)) {
			all.forEach(consumer);
		}
	}
}

Reference document should be improved about streaming supports also whether this advice accepted or not.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions