0

I have a General class which has static methods and static variables with Hibernate configuration settings and methods which return List after hitting the database. I am working on JavaFx and i recently learned its better to use Task for time consuming operations like hitting the db for a long list of data etc. So, here in my case, i created a Task object, wrote the code in anonymous inner class which contains the code for hitting the db for the LOGIN credential. The Task must return an instance of List. I intialized a Thread object inside the static method, passed Task's object in its constructor, set the daemon to true and started the Thread. However i am getting NullPointerException after running the application..

private static SessionFactory sessionFactory = null;
private static Session session = null;
private static final Transaction transaction = null;
private static final Configuration configuration = null;
private static List list;
  public static List getSelectList(final String query)
  {
      //list = null;
      System.err.println("Inside getSelectList");
      try{
      final Task <List> task= new Task <List> ()
      {
          @Override
          public List call()
          {
              try
              {
                 System.err.println("Inside call");
                 session.beginTransaction();
                 list = session.createQuery(query).list();
                 System.err.println(list);


                 session.getTransaction().commit();
                 return list;
              }
                catch (Exception e)
                {
                     session.getTransaction().rollback();
                     e.printStackTrace();
                }
              System.err.println("Outta try block");
              return null;
          }
      };

      task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
          @Override
          public void handle(WorkerStateEvent t) {
              System.err.println("Inside handle");
             list = task.getValue();
            /* for (Iterator it = list.iterator();it.hasNext(); )
                 {
                  System.err.println("Inside Set on succeeded");
                  //System.err.println( ((Login)it.next()).getUsername());   
                 } */
             }
            });

     Thread th = new Thread(task);
     th.setDaemon(true);
     th.start();


     //list=task.getValue();

      }
      catch (Exception e) {e.printStackTrace();}
      return list;

  }

Exception which i got

However, after many combinations and random permutations, things worked for me with commenting the Thread code and instead substituting it with task.run();

 /*Thread th = new Thread(task);
     th.setDaemon(true);
     th.start();*/
task.run();

Also i had to change the local variable List list = session.createQuery(query).list(); by declaring static List list; and initializing this static list = session.createQuery(query).list(); since it was throwing me the exception too even if i removed Thread code and added task.run()

 try
              {

                 session.beginTransaction();
                 //List locallist = session.createSQLQuery(query).list();
                 list = session.createSQLQuery(query).list();
                 session.getTransaction().commit();
                 return list ;
              }
                catch (Exception e){
                     session.getTransaction().rollback();

I wish to know why this happened. Why task.run() along with using static List worked for me?

Converting List to static and removing the Thread instance and using task.run(); was merely a number to different tries from my side to make my code work. i dunno the reasons. I will be greatly humbled for any explanations. Thanks in advance.

Lalit Rao
  • 551
  • 5
  • 22
  • `th.start()` executes the task's `run()` method in a background thread, and then exits immediately (i.e. probably before the `run()` method completes, so the value hasn't been computed yet). Calling `task.run()` directly executes `run()` in the current thread, so it blocks until `run()` is complete. This is already explained at http://stackoverflow.com/questions/2674174/what-is-the-difference-between-thread-start-and-thread-run – James_D Apr 07 '15 at 14:29
  • Okay, i get it. By calling task.run(), the execution is done at the same caller thread. But i wish to know why wasnt i able to create a new Thread and execute the Task in this particular Thread instead of the caller Thread? Is there any parameter am missing? i can spawn a new Thread from a static method right? – Lalit Rao Apr 08 '15 at 00:41
  • Yes, you can, but if you do that, `getSelectList()` returns `null`, because it finishes before the task completes. – James_D Apr 08 '15 at 00:53
  • With all due respect Sir, but i dont find a justified reason why the Thread finishes before the task completes? I tried the instructions given in [Oracle's documentation](https://docs.oracle.com/javafx/2/api/javafx/concurrent/Task.html) which it self suggests to pass the Task in a Thread constructor, and start this Thread manually. Also it doesn't make any sense for me to run this time consuming *Task* in the current Application thread and lose my GUI's responsiveness if. I need to find a way to delegate this Task into a new background Thread. A good justification will be greatly welcomed! – Lalit Rao Apr 08 '15 at 15:37
  • The *method* `getSelectList()` finishes before the task completes. – James_D Apr 08 '15 at 15:44
  • But how? Why is this happening? Why it finishes before completion of Task. Moreover, I wish to specify that 'th.start();' worked nicely if i transformed the 'getSelectList()' to non static method – Lalit Rao Apr 08 '15 at 15:53
  • Your method creates the task, sets the task running in a background thread, and then exits with `return list`. The thread is still running when it exits. – James_D Apr 08 '15 at 15:55
  • But `th.start();` worked nicely if i transformed the `getSelectList()` to a **non static** method. – Lalit Rao Apr 08 '15 at 15:56
  • The bottom line is that you are accessing `list` from two different threads, with no control over the order of when you are accessing it and when you are setting it. You need to restructure the code to use threads and tasks in the standard way, without sharing data like that. – James_D Apr 08 '15 at 15:58
  • Okay! I ll work on that. Thank you! – Lalit Rao Apr 08 '15 at 16:00

0 Answers0