0

I am new to Spring and I wish to implement threads. I have tried the conventional Java run() method to send a database writing task to the thread. However, this causes a NullPointerException every time I am calling the database dao or service query within the run() method. If I place the query in the constructor then it works.

I think possibly I am not able to instantiate the dao/service variable in runnable?

public class TestThread implements Runnable{
    @Autowired
    public CarService carService;   

    public TestThread(List<Car> listcar) {
        List<Car> listcar = new ArrayList<Car>();
        //This works here
        listcar = new java.util.ArrayList<Car>(carService.findAllServices(0, 10000));
        for(int i=0;i<listcar.size();i++) {         
           System.out.println("The all car services  in runnable constructor"+listcar.get(i).getName());
        }
    }

    public void run() {
        try {
            runrun();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    //This does not work
    public void runrun() throws Exception {
        List<Car> listcar = new ArrayList<Car>();
        listcar = new java.util.ArrayList<Car>(carService.findAllServices(0, 10000));
        for(int i=0;i<listcar.size();i++) {         
            System.out.println("The all car services  in run method "+listcar.get(i).getName());

        }
    }
}

TestThreadCallController.java:

@Controller
public class TestThreadCallController {

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public @ResponseBody void FindyourCarService() throws IOException{         
        TestThread th=new TestThread(listcar);
        new Thread(th).start();
        ApplicationContext context = new ClassPathXmlApplicationContext("test-Thread.xml");

        TestThread th1 = (TestThread) context.getBean("TestThread");       
        new Thread(th1).start();
    }
}

test-Thread.xml

bean initialization code:

    <bean id="TestThread" class="com.test.thread.domain.TestThread">
    </bean>
Danielson
  • 2,605
  • 2
  • 28
  • 51
s_ag
  • 82
  • 1
  • 7
  • 1
    And how are you creating `TestThread`? You'll have to remember that in order for `@Autowired` to work Spring needs to manage the object, and you're probably instantiating it yourself via `new` *(side note: always include all relevant code in the question)*. The very fact that you're creating a `Runnable` for a task like this suggests that you should start by reading the basic guides. – kryger Feb 17 '15 at 15:44
  • possible duplicate of [Why is my Spring @Autowired field null?](http://stackoverflow.com/questions/19896870/why-is-my-spring-autowired-field-null) – kryger Feb 17 '15 at 15:44
  • Thanks kryger, I tried using both new and application context, since it gives error for runnable. (My runnable actually is to write to database, since dao not working for run method, I first want to try this) – s_ag Feb 17 '15 at 16:36
  • concurrent database modifications sounds like a bad idea to me! – ConMan Feb 17 '15 at 16:44
  • Don't do this manually. If you want asynchronous database access, use Spring's `@Async` support. – chrylis -cautiouslyoptimistic- Feb 17 '15 at 18:18
  • Great question. And good top answer, fixed my problem, yes, I used "new" in a scheduled task, and forgot that I needed to autowire it. This after 25 years of java. Its OK. Repeat. – tom Apr 15 '23 at 13:12

1 Answers1

0

Yeah, agree, bad idea doing this manually. Let Spring do it. Put a service for the DB behind A Spring Integration gateway & return a Future. boom. done. @Async works - but its more fun to play with SI.

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
John Thompson
  • 514
  • 3
  • 7