0

Here is the code for the repository-

public interface QuartzDetailsRepository extends JpaRepository<QuartzDetails, Serializable>{

QuartzDetails findById(int id);

}

Below is the code in the controller.

@Autowired
private QuartzDetailsRepository quartzDetailsRepository;

@Autowired
private QuartzDetails quartzDetails;

public void func(QuartzDetails qz){
          quartzDetails = quartzDetailsRepository.save(qz);
          System.out.println(quartzDetails.toString());
}

This code works just fine when I execute it for the first-time. However, If I call this function the second time the autowired quartzDetails holds the values of the first-time execution.

As a work-around I did the following

 public void func(QuartzDetails qz){
       QuartzDetails qdz = quartzDetailsRepository.save(qz);
       System.out.println(qdz.toString());
 }

My question is - why does the autowired object behave like that? Why are the values of the first time execution persisting in it?

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
davyjones
  • 185
  • 15
  • 2
    Is `QuartzDetails` a data class? Why would you autowire it? This leads to state in your controller, which is just bad. – Tobb Jun 13 '16 at 09:33
  • 3
    Why are you autowiring `QuartzDetails` into the controller? Spring beans are by default singletons. It seems like you should only autowire the `QuartzDetailsRepository` into the controller, and then call `findById` on it to find the `QuartzDetails` instance you want to work with. – Jesper Jun 13 '16 at 09:33
  • @Tobb Yes, QuartzDetails is a data class. I'm new to Spring so I don't understand what you mean by **state in your controller**. Can you please guide me there? – davyjones Jun 13 '16 at 09:40
  • @davyjones After saving you got an instance of `QuartzDetails` that you shouldn't expose to a controller. – Roman C Jun 13 '16 at 09:48
  • 2
    In Spring, all beans are `singleton` by default, meaning that there are at most 1 object of the class. So you have one controller object, which is shared by all users. In order to avoid bugs, it's important for these singletons to be stateless, that means that the only allowed class variables are constants and other stateless beans. Say both you and I call the same method at once, and that this method first assigns something to a class variable, and then does stuff to it. Depending on the thread management (of which neither of us control), we might have a situation like this (continued...) – Tobb Jun 13 '16 at 10:19
  • 1
    1. Your object is assigned to the variable. 2. My object is assigned to the variable. 3. You do stuff to the assigned object (which is mine!!) 4. I do stuff to the assigned object (which might not work, since you already done stuff to it.) – Tobb Jun 13 '16 at 10:20
  • 1
    To sum it up: Never ever store data objects in the class variables in a spring bean (unless your bean is stateful by design, which is rarely necessary). Following from this: Don't autowire data objects into your spring beans. – Tobb Jun 13 '16 at 10:22
  • @Tobb I understood your point. How do you suggest I should approach if I want to create a QuartzDetail object? I mean I can use a new() to create it but wouldn't that defeat the purpose of using Spring? – davyjones Jun 13 '16 at 10:32
  • Using new for data objects is fine with Spring. Spring is meant for business logic classes (the ones that define "how"), the data classes (the ones that define "what") can be handled like plain java objects (or entities). – Tobb Jun 13 '16 at 11:26

0 Answers0