I am facing a weird scenario with the Spring NamedParameterJdbcTemplate. I have a project setup with context.getBean()calling for a Spring NamedParameterJdbcTemplate. This is being called as part of initial setup through the #PostConstruct method. Essentially, the post construct method makes a call to the database to get a few environment related setup to be done.
Now, the getBean call to the NamedParameterJdbcTemplate bean takes a long time -- in fact under Eclipse I've had to wait for more than 5 minutes and never got an instance. However, the same code works perfectly fine if I use a #Inject instead of getBean.
Secondly, the same setup also has a bean for plain JdbcTemplate. If I get this bean and then call the bean with NamedParamJdbcTemplate, then there is no issue. The problem seems to be only when the NamedParamJdbcTemplate is the first bean call.
Is there a difference in this being called first vs second time? Aren't we supposed to call this as the first bean? I am unable to find any documentation with regards to this.
Thanks,
Aravind
Related
Spring is auto-wiring in a request parameter - let's call it "bob".
I don't know where nor how it is doing this, so I cannot debug it. What spring specific code (using intellij, so I can at lest set a conditional) would be appropriate to find where the auto-wiring of the request parameter is happening, so I can work out what the system is doing?
I think I understood the question, so I will try to answer it as best as I can.
You are facing a dilemma of choosing between managing your instances, or letting Spring manage them. If you let Spring manage dependency injection, you will often face situations where you wish you had more fine control over the beans lifecycle.
By default, Spring beans are "singletons", which means that only one
instance of that object will be created, and every class that demands
a dependency injection of that object will receive the same instance.
The first step on beans lifecycle is its construction. You can setup a breakpoint to catch that moment on any method annotated with #PostConstruct. This article describes the need of running some code on bean initialization, and how it is solved by this annotation. For example:
public class AnyBean {
#PostConstruct
public void init(){
// any code or breakpoints inserted here will
// be run whenever an instance of this bean is created.
// if a singleton bean, only one instance is created and,
// only one #PostConstruct will be called.
// If a bean is a prototype bean, a new instance will be created
// for every dependency injection, and hence one #PostConstruct
// will be called for each.
}
}
I am Trying to update DB Schema whenever application version updated.
Some People said It is not a good Function but I wanna try whether I use it or not.
I Succeed Update schema when application booted.
but I have to change the timing that schema updated. and It is between after Bean object DI finished and before #PostConstruct work.
is it impossible, just before #PostConstruct work whether DI is finished or not.
how can I do this?
PS. I have known flyway work similar function compared I am making. but I want to make similar thing by my self.
When spring bean gets initialized, spring guarantees that all the properties will be injected (by means of applying constructor injection, setter injection or field injection)
So First of all spring calls bean's constructor
Then (if the fields are not set yet) it tries to inject fields
And only after that, it calls #PostConstruct
So you should be able to access the database from the post-construct method of the bean.
The context of this question is within spring-boot, using spring-data-jpa and hibernate.
A colleague wrote an #Service and annotated the service method with #Transactional. The service method loads an entity, and subsequently hits a one-to-many lazily loaded collection (fetch = FetchType.LAZY). The service method is invoked by some custom delegator, which i will come back to. This works fine when invoked from a #RestController endpoint.
When i invoked the service from a camel route (again via the custom delegator) it barfed with a lazy initialization exception.
On digging, found that the service implements an interface, the custom delegator looks up the service (it is injected so has proper proxy) and calls a method
on the interface which is actually a java-8 default method. This default-method then locally calls the #Transactional method.
So there's the problem :- this is a LOCAL method call so the aspecting/proxy-ing of the #Transactional annotation is not done (we use aspectJAutoProxy) so the method is NOT invoked within a transaction, so the lazy-loading SHOULD fail. And to double-check, also tried it via an #Scheduled annotation: same behaviour. Barfs like it should.
My Question: So why does it work when called from the #RestController? This is driving me nuts!
There is no transactional annotation on the rest controller endpoint.
I added some debug code to the service using TransactionSynchronizationManager.isActualTransactionActive() and it shows that in no case is there a transaction, even when being called via the controller endpoint.
So why does the lazy loading work when being called from the controller?
I dumped all SQL and at no points are the lazy-collection already loaded, so they are not in any hibernate cache.
I remember reading once that lazy loading was a hint, not a command, but still... why does it work in that one case?
after being perplexed by this on many occasions, have stumbled across the answer:
sprint-boot is doing an open-entity-manager-in-view behind our backs via the OpenEntityManagerInView interceptor. Had no idea this was going on.
See this excellent answer from Vlad Mihalcea https://stackoverflow.com/a/48222934/208687
When your method annotate to transactional hibernate session close after return method , if object that return from method have lazy , lazy property not load and you get exception that session close. You can use fetch in query or using OSIV
I want my server to do some database cleanup on startup. I tried adding a #PostConstruct method to a service to do this, however #Transactional doesn't work there. Any changes I make aren't being persisted. How can I get this done? Can I create a new bean with specific callbacks on it?
You can just call another transactional resource in #PostConstruct which does the work, because injection is done then. So DbPopulator can use UserService and whatsoever in its #PostConstruct and everything is transactional and nicely separated again. Singleton beans are constructed at startup afaik, so no additonal setup required.
These days i am learning spring by http://static.springsource.org.
I am facing some problem in this page http://static.springsource.org/docs/Spring-MVC-step-by-step/part4.html. i am not getting it clearly that when setProductManager method is called when InventoryController class is invoked. I know that this works as a front controller and when hello.jsp page is requested ,ModelAndView method is executed of InventoryController. but i want to know that when setProductManager method is called.
Any help would be appreciable.
Spring is an ioc container and in this particular example the dependency-injection is implemented using setters (setter injection). Basically the container takes care of supplying your bean (controller in this case) with necessary dependencies.
Back to your question: dependency injection is performed before your bean is ever used by the framework or any other beans requiring it. Furthermore, controllers are singletons. This means setProductManager is called before any request is handled by the controller - when the application is started. And because there is only one instance of the controller - it is called once.