I am wanting to stream some data out the database after a Spring Batch Tasklet step
public class TaskletUpdateAll implements Tasklet {
@Autowired
private AdRepository adRepository;
@Override
public RepeatStatus execute(StepContribution sc, ChunkContext cc) {
return RepeatStatus.FINISHED;
}
@AfterStep
@Transactional(readOnly = true)
public ExitStatus afterStepMethod(StepExecution stepExecution) {
try (Stream<Pair<String, String>> adStream = adRepository.streamAll();) {
adStream.forEach((Pair ad) -> {
// Process ad
});
}
return ExitStatus.COMPLETED;
}
}
Despite the fact the method that calls the stream is annotated with @Transactional(readOnly = true)
it still returns the following error message:
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: You're trying to execute a streaming query method without a surrounding transaction that keeps the connection open so that the Stream can actually be consumed. Make sure the code consuming the stream uses @Transactional or any other way of declaring a (read-only) transaction.
The AdRepository
class follows the advice from here so the streamAll
method looks like this:
@Repository
public interface AdRepository extends JpaRepository<Ad, Long> {
@QueryHints(value = @QueryHint(name = "HINT_FETCH_SIZE", value = "" + Integer.MIN_VALUE))
@Query(value = "SELECT href, provider FROM ad", nativeQuery = true)
Stream<Pair<String, String>> streamAll();
...
}
I have also made sure to include the @EnableTransactionManagement
annotation in the configuration class for the Job as told to by the documentation.
...
@Configuration
@EnableTransactionManagement
public class MainTaskletsConfig {
...
Any idea if what I am doing is even possible and if it is what I am doing wrong?