Initializing tables on spring boot startup - spring

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

Related

Spring Kafka Listener shutdown Application

I have an application that creates 3 KafkaListener per configuration in the ConcurrentKafkaListenerContainerFactory if any of these Listeners throws a specific Exception. I would like to shutdown the entire spring application.
Since these errors are non recoverable and need manual intervention.
How would i go about doin this?
Do i just inject the ApplicationContext into the Listener and close the application from there?
Or is there a more appropriate way of handling this?
That's one way, or you could just call System.exit(1).

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.

Spring Application Context Initialization

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.

how can we use addShutdownHook in project?

i saw some code use ShutdownHook like this
Runtime.getRuntime().addShutdownHook(new Thread(){
ConfigurableApplicationContext.stop();
//close spring context;
threadpool.shutdownnow();
//close theadpool
});
is there anything useful to do like this?
i thought
when jvm exit ,maybe thread will be shutdown immediately
and spring context will close tooï¼›
what shall we do next when we need to call System.exit() ?
It really depends on your application and the lifecycle of your objects and those threads you appear to have outside of your context. If you are running the spring container inside a standalone java process, then trapping the shutdown hook like this is one way to do that. Another way is to have it listen on a tcp port and send a command to begin the shutdown process. If you are running in a web container like tomcat, then you should follow the standards on normal webapp shutdown, which Spring supports with Context Listeners.
I would also consider redesigning your app so that the threads are all managed with a bean that lives inside your spring container. For instance using a bean that is configured with directives (attributes) for start/stop methods and then that bean would use an Executor for thread pooling. This way, your shutdown is ONLY shutting down the Spring container, and Spring provides very good support for orderly shutdown of beans. One of those beans is your object holding the threads within the Executor. Its a much cleaner way than trying to integrate Spring beans with external threads.
Hope this helps.

shutdown ehcache CahceManager in stateless bean

I would like to use ehcache in stateless EJB. As I know if I get a singleton instance of CacheManager then I have to shutdown this instance when I don't need it. However it causes a big overhead for me as a lot of time is needed to create the CacheManager instance if I shutdown it at each call.
Or shouldn't I bother to shutdown the CacheManager in EJB? Won't it cause any issue?
Thanks!
Per EhCache documentation (http://ehcache.org/documentation/operations/shutdown) it's a good practice (and in some case required practice) to shutdown EhCache properly.
Either way, Should be easy to implement: I think you should register a shutdown hook for your EJB (check post EJB application shutdown hook) and in that hook, simply call the CacheManager.shutdown() method.
Hope that helps.

Resources