How to get a new Connection from Hibernate SessionFactory after the DB restart without restarting the tomcat? - spring

In my web application I am using hibernate & spring. The Hibernate SessionFactory object is being injected as a spring bean at the time of tomcat server start up. Normally it is working fine. But the problem arises when I shut down or even restart my database.
After restarting my database if I retrieve a session from Hibernate SessionFactory object and want to execute query i am getting org.hibernate.exception.JDBCConectionException: Could not execute query exception.
To overcome this problem I need to restart the tomcat server. After restart it creates the new SessionFactory object, so I don’t get the exception.
In a situation how can I get a new fresh connection with the database, so that I don’t need to restart the server again & again.

SessionFactory rebuild worked for me
Our app is using tomcat, hibernate(3.5.1) and Oracle db (there are actualy two instances - one is the main for the application and the second one - remote)
sometimes remote db restarts, after that exception occurs on each call
JDBCConnectionException:could not execute query
Caused by: SQLRecoverableException: No more data to read from socket
Fistly I added to configuration
hibernate.dbcp.validationQuery=select 1 from dual
hibernate.dbcp.testOnBorrow=true
hibernate.dbcp.testOnReturn=true
but without result.
Then I tried to close sessions and recreate it.
Finally what worked for me - after this exeption
sessionFactory recreate
sessionFactory.close();
sessionFactory = annotationConfiguration.buildSessionFactory();

This is not really Spring or Hibernate related. What you need to do is to setup your JDBC connection pool to test connections before returning them to whoever needs them (e.g. Hibernate). If the pool discovers that the connection in the pool is broken, it dicards it and tries another one from the pool. If all connections in the pool are broken, the pool will try to create new ones. Everything is transparent and your application won't even notice.
Which connection pool you use? In dbcp set validationQuery to"SELECT 1" nd consider setting: testOnBorrow=true, testOnReturn=true and testWhileIdle=true. For c3p0 check out the documentation.

Related

Is it possible to disable a Spring Boot datasource configuration based on unavailability of a connection to a DB

We have an application that uses several data sources. A DB underlying one of those data sources is down at the moment: IOError. Network adapter couldn't establish the connection & Socket read timed out.
Is there an annotation (or other means) of configuring Spring Boot such that it bypasses the culprit data source and still starts up: the DB is not essential in current development work. spring.datasource.continue-on-error=true doesn't seem to work. This is Spring 2.2.2.RELEASE.
using multiple datasource, so when your apps fail at start up your apps still work, i mean using memory db / sqlite to handle fail at connection error...

MyBatis+Spring+Jersey with Oracle Seems to reuses SQL sessions

I'm creating a rest service using MyBatis 3.3.1, Spring 4.3, Jersey 2.22 and Oracle 12c. My transactions are being managed by Spring using the DataSourceTransactionManager and the #Transaction annotaion. I am also using a MyBatis pooled data source as my javax.sql.DataSource. What I don't understand if why database sessions are being reused.
In my application, I am setting an oracle client identifier: DBMS_SESSION.SET_IDENTIFIER("my id"). With the debug logging statements, I can see MyBatis creating new sessions for each of the MyBatis sql operations. I also have debug to print out the database session identifier from DBMS_SESSION.UNIQUE_SESSION_ID.
What I don't understand is that if I access my rest endpoint multiple times, the unique session id is the same and the identifier from my last access is still set.
Shouldn't a new oracle session be used every time MyBatis gets a new SQLSession? Why is the oracle session always the same?
Thanks.
Session in Oracle is bound to a connection.
You are using connection pooling so after one rest request is finished the connection is returned to the connection pool. Session is not terminated in this case.
You probably want to clear identifier on returning connection to pool and setting it on retrieving connection from the pool. The exact way to do that depends on the connection pool you are using. For built-in mybatis connection pool see this answer.

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.

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.

Spring DatasourceTransactionManager not release connection after commit/rollback

I have an Enterprise Application (ear) deployed in this configuration enviroment:
Weblogic 12c (12.1.1) + Oracle RAC 11g (release 2).
Web Module is an MVC application, implemented with Struts 2 and Spring-framework (3.2.2) for core services. Spring JDBC is used for database access with simple JdbcTemplate for single statements and DatasourceTransactionManager for complex ones. I noticed a strange behavior when I enable Weblogic jdbc logs. When I start a new transaction, I can see jdbc info logs about transaction creation, retriving jdbc connection from weblogic datasource pool and setting autocommit property to false value over connection itself. But I can't see transaction releasing connection log, and restoring autocommit flag to true value after commit/rollback invocation.
It's possible that Spring Transaction Manager does not release jdbc connection and does not restore "autocommit" value flag (to true)? After a while I can see within my application some persistent locks on db tables, causing an overall defect of my application and that I would not have depended on the behavior of the transaction manager.
Has anyone noticed a similar behavior?
Is it possible that jdbc connection is not released by the framework and it can compete in multiple transactions (as seen in jdbc log)?
Thanks
Paolo
Since you are using managed DataSource from WebLogic (JNDI?) you have to use managed TransactionManager as well:
<tx:jta-transaction-manager/>
should be enough:
if (weblogicPresent) {
return WEBLOGIC_JTA_TRANSACTION_MANAGER_CLASS_NAME;
}
And it is instead of that DatasourceTransactionManager.

Resources