Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I determine the DataSource being used by a Hibernate Session?

I have several unit tests that should be using a HSQLDB but I know some of them are actually hitting a physical DB. I want to add a check to the test to make sure that the DataSource being used is for HSQLDB and not the live DB.

From a hibernate session object (org.hibernate.classic.Session), How do I check the DataSource

Update: I also have access to the session factory (org.hibernate.impl.SessionFactory).

Details: Hibernate 3.2

like image 450
Mike Rylander Avatar asked Mar 15 '13 20:03

Mike Rylander


People also ask

What is hibernate connection DataSource?

hibernate. connection. datasource property is used to provide the DataSource name that will be used by Hibernate for database operations.

Which is used to open a session in hibernate?

Hibernate SessionFactory openSession() method always opens a new session. We should close this session object once we are done with all the database operations. We should open a new session for each request in multi-threaded environment.

What is Session beginTransaction in hibernate?

In hibernate framework, we have Transaction interface that defines the unit of work. It maintains abstraction from the transaction implementation (JTA,JDBC). A transaction is associated with Session and instantiated by calling session. beginTransaction().

Can Hibernate session have multiple transactions?

The Hibernate transaction API delegates the begin/commit/rollback to the JDBC Connection for local transactions and to the associated UserTransaction for JTA. Therefore, you can run multiple transactions on the same Hibernate Session, but there's a catch.


2 Answers

Regardless of wrappers and concrete implementation of Hibernate/Spring and so on, you may check not DataSource, but database type (and this might be suitable).

The idea is in the usage of DatabaseMetaData and check type against it (as Hibernate detects dialect):

private boolean isTestDb(Session session) {
    return session.doReturningWork(new ReturningWork<Boolean>() {
        @Override
        public Boolean execute(Connection connection) throws SQLException {
            DatabaseMetaData metaData = connection.getMetaData();
            return metaData.getDatabaseProductName().startsWith("HSQL");
        }
    });
}

Note, that body of method can be changed in the way you want (check JDBC URL, check driver name, check almost anything).

Edit: approach above is working for hibernate 3.5+.

For Hibernate earlier version(e.g. 3.2) it might be even easier:

private boolean isTestDb(Session session) {
    Conection connection = session.connection();//deprecated method, which was dumped in hibernate 3.5+
    DatabaseMetaData metaData = connection.getMetaData();
    return metaData.getDatabaseProductName().startsWith("HSQL");
}
like image 132
n1ckolas Avatar answered Oct 11 '22 13:10

n1ckolas


If it's a subclass of AbstractTransactionalDataSourceSpringContextTests, then have you tried getJdbcTemplate().getDataSource()?

Otherwise you could try

((SessionImplementor) session).getJdbcConnectionAccess().obtainConnection()
       .getMetaData().getDatabaseProductName()

But it that's kind of disgusting. :) And seems to get introduced in Hibernate 4.x.

Edit:

On older versions use the now deprecated:

    ((SessionImpl) session).getSessionFactory().getConnectionProvider()
                           .getConnection().getMetaData().getDatabaseProductName();
like image 44
zagyi Avatar answered Oct 11 '22 14:10

zagyi