0

Working on my first Java project I can't seem to get around this probably basic problem: In a JavaFX application I have a DAO class, which starts a service to get values from a mysql db, builds an object from it and returns the object to the caller. But the object never gets build, because the return happens before the service has succeeded.

public IQA getQA(int id) throws SQLException {      
        try {           
        GetQuizService getQuizService = new GetQuizService();
        getQuizService.restart();
        getQuizService.setId(id);
        getQuizService.setOnSucceeded(e -> {
            this.quiz = getQuizService.getValue();
        });         
    } catch (Exception e) {
        System.err.println(e);
    }
    return quiz;
}

The service works fine, inside the onSucceeded action the object is present, but how can I make the return wait until the service has finished?

As requested here's a minimal version of the GetQuizService

public class GetQuizService extends Service<Quiz> {
    private int id;
    private Quiz quiz;
    public void setId(int id) {
        this.id = id;
    }

    @Override
    protected Task<Quiz> createTask() {
        return new Task<Quiz>() {
            @Override
            protected Quiz call() throws Exception {
                // Severall calls to db here, Quiz object gets constructed
                return quiz;
            }
        };
    }
}
Samuel Philipp
  • 10,631
  • 12
  • 36
  • 56

1 Answers1

1

The problem in your code is, that you service methods are executed asynchronously.

You should return the Task<Quiz> instead of quiz and use that to update your frontend if the result is received (I have to few information to create an appropriate example for you).

Another option is to pass a callback to your service, which is invoked when the result is received instead of returning the quiz.

public void getQA(int id, QuizReceiver callback) throws SQLException {
    try {
        GetQuizService getQuizService = new GetQuizService();
        getQuizService.restart();
        getQuizService.setId(id);
        getQuizService.setOnSucceeded(e -> {
            callback.quizReceived(getQuizService.getValue());
        });         
    } catch (Exception e) {
        System.err.println(e);
    }
    return quiz;
}
public interface OuizReceiver {
    void quizReceived(IQA quiz);
}
Samuel Philipp
  • 10,631
  • 12
  • 36
  • 56
  • Thanks! In the end I think this points to an design problem in the project, which I should address. – rookie_senior Mar 11 '19 at 14:50
  • 1
    Thanks again Samuel! For anyone interested I have found [this thread](https://stackoverflow.com/questions/30249493/using-threads-to-make-database-requests) addresses the situation I'm facing pretty well – rookie_senior Mar 11 '19 at 21:50