3

I'm trying to perform a .findAll() on a repository interface that extends from CrudRepository. I'm trying to do this inside a @Async method using a @Autowire implementation of the repository. When I run the following code the @Async thread waits forever at the UpdateTasksService List<Task> tasks = (List<Task>)taskRepo.findAll();

When I remove the @Async annotation from the updateTasks() method, the program runs as expected and prints all .toString() data.

My questions are:

  1. Why can't I use the @Autowired TaskRepository taskRepo; inside a @Async method?
  2. How can I use the repository inside a @Async method?

Thank you in advance!

ScheduleComponent

@Component
public class ScheduleComponent {

    @Autowired
    UpdateTasksService updateTasks;

    @PostConstruct
    public void update(){
        Future<Void> updateTasksFuture = updateTasks.updateTasks();
        try {
            updateTasksFuture.get();
            System.out.println("Done");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

UpdateTaskService

@Service
public class UpdateTasksService {

    @Autowired
    TaskRepository taskRepo;

    @Async
    public Future<Void> updateTasks() {
        System.out.println("The method starts");
        List<Task> tasks = (List<Task>)taskRepo.findAll();
        for(Task task: tasks){
            System.out.println(task.toString());
        }
        return new AsyncResult<Void>(null);
    }
}

TaskRepository

@Repository
public interface TaskRepository extends CrudRepository<Task, String> {
}
  • maybe this? [enter link description here](https://stackoverflow.com/questions/19935809/async-and-transactional-not-working) – WON JONGPIL Jun 02 '21 at 16:02

1 Answers1

0

I had the same issue and noticed that this behavior does not occur when a query is based on the JDBC API (not the JPA repository) or when the query is defined with @Query in the SpringData repository. As a workaround, I called a flush on one of the repositories in PostConstruct. I still don't know why this happens.

Workaround:

 @Service
    public class UpdateTasksService {
    
        @Autowired
        TaskRepository taskRepo;
        
         @PostConstruct
        public void init() {
            //Workaround to a async method that waits forever when called  
            //from PostConstruct from another component
            taskRepo.flush();
        }
    
        @Async
        public Future<Void> updateTasks() {
            System.out.println("The method starts");
            List<Task> tasks = (List<Task>)taskRepo.findAll();
            for(Task task: tasks){
                System.out.println(task.toString());
            }
            return new AsyncResult<Void>(null);
        }
    }