GOOGLE ADS

Dienstag, 26. April 2022

Wie kann ich mit springboot auf ein Repository innerhalb einer asynchronen Methode zugreifen?

Ich versuche, eine .findAll()auf einer Repository-Schnittstelle auszuführen, die sich von CrudRepository erstreckt. Ich versuche dies innerhalb einer @AsyncMethode mit einer @AutowireImplementierung des Repositorys zu tun. Wenn ich den folgenden Code ausführe, @Asyncwartet der Thread für immer auf den UpdateTasksService
List<Task> tasks = (List<Task>)taskRepo.findAll();

Wenn ich die @AsyncAnmerkung aus der Methode updateTasks() entferne, läuft das Programm wie erwartet und gibt alle.toString()-Daten aus.

Meine Fragen sind:

  • Warum kann ich das @Autowired TaskRepository taskRepo;Innere einer @AsyncMethode nicht verwenden?

  • Wie kann ich das Repository innerhalb einer @AsyncMethode verwenden?

  • Vielen Dank im Voraus!

    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> {
    }


    Lösung des Problems

    Ich hatte das gleiche Problem und bemerkte, dass dieses Verhalten nicht auftritt, wenn eine Abfrage auf der JDBC-API (nicht dem JPA-Repository) basiert oder wenn die Abfrage mit @Query im SpringData-Repository definiert ist. Als Problemumgehung habe ich einen Flush für eines der Repositories in PostConstruct aufgerufen. Ich weiß immer noch nicht, warum das passiert.

    Problemumgehung:

     @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);
    }
    }

    Keine Kommentare:

    Kommentar veröffentlichen

    Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

    Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...