How to determine the data source used by a Hibernate session?

I have some unit tests that HSQLDB should use, but I know that some of them actually get into the physical database. I want to add validation to the test to make sure that the DataSource used is for HSQLDB and not for live DB.

From a hibernation session object ( org.hibernate.classic.Session ) how to check a DataSource

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

Details: Hibernate 3.2

+6
source share
4 answers

Regardless of the shells and the specific implementation of Hibernate / Spring, etc., you can check not the DataSource, but the database type (and this can be convenient).

The idea is to use DatabaseMetaData and type check against it (since Hibernate detects a 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 the body of the method can be changed the way you want (check the JDBC URL, check the driver name, check almost everything).

Edit : The above approach works for 3.5+ sleep mode.

For an earlier version of Hibernate (e.g. 3.2) this might be even simpler:

 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"); } 
+6
source

If this is a subclass of AbstractTransactionalDataSourceSpringContextTests , then you tried getJdbcTemplate().getDataSource() ?

Otherwise you can try

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

But this is so disgusting. :) And it seems to introduce in Hibernate 4.x.

Edit:

In older versions, use legacy versions:

  ((SessionImpl) session).getSessionFactory().getConnectionProvider() .getConnection().getMetaData().getDatabaseProductName(); 
+2
source

This is a common hack and may not work, since you need to drop certain classes that your installation might not use.

 SessionFactoryImpl factory = (SessionFactoryImpl) session.getSessionFactory(); // or directly cast the sessionFactory DatasourceConnectionProviderImpl provider = (DatasourceConnectionProviderImpl)factory.getConnectionProvider(); DataSource dataSource = provider.getDataSource(); 

factory.getConnectionProvider() returns an instance of ConnectionProvider (interface), which can be implemented by any number of classes . One of them is DatasourceConnectionProviderImpl , which can then be used to obtain a data source.

DatasourceConnectionProviderImpl should be the default unless you are using the hibernate C3P0 or Proxool pools.

+1
source

If you want to discover a db provider without opening a new connection, you might find it useful to use the dialect class.

  String dialectName = ((SessionFactoryImplementor)sessionFactory).getDialect().getClass().getSimpleName().toLowerCase(); if(dialectName.contains("oracle")) ... else if(dialectName.contains("mysql")) ... 
0
source

All Articles