Spring Application Context Initialization - spring

In my Spring Application, at the time of context Initialization. The DB is not available, it will come up after some time (Due to DB redundancy). In this scenario, my spring application initialization should be delayed or the application should do retry for DB connectivity. How to achieve the same via Spring.
Srirama.

I'd suggest investigating the ApplicationContextInitializer. It is meant to be used for setting up your context before most of the magic of spring initialization happens.
I'm not sure if it is designed for your use case, but no beans are initialized when the initialize method is called during startup.
The example provided in the link deals with properties, but I see no reason why you should not create your own manually created connection and wait for it's readiness.

Thanks for the reply.
My application is initialized by means of C3P0. Here C3P0, is trying to reconnect to DB only for 30 times (the default configuration for acquireRetryAttempts) and after that it is saying failed to create the application beans.
Changed the configuration for acquireRetryAttempts to -1, so that C3P0 is retrying indefinitely till the DB connection is successful. Basically my app. initialization should be delayed till the DB comes up.
Srirama.

Related

Should I use #PostContruct or Context refresh event to connect to CTI server

I am developing a REST service which will connect to a CTI server through TCP and the connection will be kept opened until the my REST service is running.
Currently I am reading the server parameters from properties file and creating bean, after the bean is constructed, the server connection will be initiated using #PostConstruct. Is it good to use #PostConstruct for this scenario or should I use context refresh event.
I tested application using both #PostConstruct and context refresh, both are working good how ever I want to follow the best practices.
Note : I searched the forum and got some answers, but not related to my scenario
Technically there is no difference. You have already tested that part. I think #PostConstruct makes more sense mainly because the connection you are creating is specific to this bean. Creating a new ApplicationContextListener wouldn't make much sense as the connection is not at a context level.

How to make spring servlet load-on-startup wait after tomcat jndi (global resources) are loaded

I have a Spring servlet called with load-on-startup = 1 and it requires a database connection, but sometimes, connection is null and the appLoader servlet fails. The connection is null because tomcat didn't had the time to load the global resources properly.
Question : How do I ask Spring to wait for jndi proper loading? I mean, order it in some way.
Dirty solution : Make another servlet with active wait and waiting for a working connection before calling my appLoader...
1) The job of <load-on-startup> is to start a servlet at the time of deployment. It just initiates(starts) the process after that it has no control over that servlet.
The entire control of the started servlet is in the hands of the web container.
The behaviour of the web container can be programmatically controlled using Event Handling mechanism.
2) Events are basically occurrence of something. Changing the state of an object is known as an event.
2.1) You can handle the events of web container using event listeners of servlet and perform some important tasks such as creating tables of the database, creating database connection object etc. at time of deploying the project.
There are many Event classes and Listener interfaces in the javax.servlet and javax.servlet.http package.
You can use ServletContextListener to store the connection object in the context attribute and later fetch that connection object from servlet context.
Here are few examples where database connection object is stored in servlet context. example1 example2 example3
2.2) You can use Event Handling mechanism of spring framework.
In spring you can poll your database connection using ContextStartedEvent that is raised when an ApplicationContext gets started.
Here, are some spring events with example.

Initializing tables on spring boot startup

I have a spring boot application, in which I need to initialize the tables based on some configuration. I am using managed transactions using #Transactional. My problem is that I do not know when app is ready to make DB transactions.
I created a bean which reads the configuration and updates the tables, but it gets an exception at that point:
Could not obtain transaction-synchronized Session for current thread
I have tried that if I wait sprintboot to start and make the same transactions through HTTP requests, then there is no problem. So it seems to be a timing problem. I have also tried moving the code to #PostConstruct of bean but it does not fix the issue.
How can I know that app is ready for DB transactions? Any help will be much appreciated.
You can listen on some events Spring is publishing.
See here
You properbly need to listen on this even: ContextRefreshedEvent
The simplest and cleanest way of performing the initialization should be by making your bean implement ApplicationListener for ContextRefreshedEvent and then handling the initialization in the onApplicationEvent method. This way, your initialization will run when Spring's whole application context is initialized

Spring Data when does it connect to the database

I have been researching Spring Data Rest especially for cassandra and one of the questions my coworkers and I had was when does Spring Data connect to the database. We don't always want a rest controller to connect to the database so when does spring establish a connection if say we had a class extend the CRUDRepository? Does it connect to the database during the start of application itself? Is that something we can control?
For example, I implemented this example on Spring's website:
https://spring.io/guides/gs/accessing-data-rest/
At what point in the code does spring connect to the database?
Spring will connect to the DB as soon as the Datasource get initialized. Basically, Spring contexts will become alive somehow (Web listeners, manually calling them) and start creating beans. As soon as it reaches the Datasource, connection will be made and the connection pool will be populated.
Of course the above is based on a normal out of the box configuration and everything can be setup up to your taste.
So unless, you decide to control the connections yourself, DB connections will be sitting there waiting to be used.
Disagree with the above answer.
As part of research i initiated the datasource using a bean configuration and then changed my database password(not in my spring application but the real db username password)
The connection stays for a while and then in some point of time (maybe idle time) it stops working and throws credential exception.
This is enough to say the JPA does not keep the connection sitting and waiting to be used but uses some mechanism to occupy/release the db connection as per the need.

How to access EJB bean through context lookup from ServletContextListener

Need to call a EJB service from the servlet context listener's contextInitialized() method. Application is running on JBOSS, though the context listener works fine, I'm not able to access the EJB bean through JNDI look up.
Because the web deployment in JBOSS happens before EJB beans are bound with JNDI tree. How to overcome from this? Is there a way to configure JNDI bind early or start the web deployment later once EJB's are completely deployed?
I had put Thread.sleep() before the service call in the contextInitialized() method, it is working fine in my JBoss5.1.0 GA, and the same did not work in other machines JBoss of same version.
Applications needs this because, we want to load some master data from the DB and make it available in the web layer (kind of caching). Does JBOSS startupmbean suit this requirement? If yes how can I make the data available to web layer?
Also if any alternative ways are available, please suggest.
Poll for the EJBs in contextInitialized(). So instead of just sleeping for a certain time, try to connect to the EJB. If that fails, sleep, and retry, until the EJBs are available. In this case the context initialization is blocked.
Implement the cache as a lazy one: Fill the cache during the first query (and use the same polling procedure: connect to the EJB, retry until it becomes available). In this case the cache blocks.
You could split your deployment into two parts: One for the EJBs, one for the web application. Then deploy the first, and delay deployment of the web application until the EJBs are bound (either by watching the log file or by trying bind to the EJB from a command line app)

Resources