我有几个应该使用HSQLDB的单元测试,但我知道其中一些实际上正在使用物理数据库。我想在测试中添加一个检查,以确保所使用的DataSource用于HSQLDB,而不是实时DB。
从hibernate会话对象(org.hibernate.classic.Session
),如何检查DataSource
的更新
我也可以访问会话工厂(org.hibernate.impl.SessionFactory
)。
详细信息: Hibernate 3.2
答案 0 :(得分:7)
无论Hibernate / Spring等的包装器和具体实现如何,您可以检查不是DataSource,而是检查数据库类型(这可能是合适的)。
这个想法是使用DatabaseMetaData并检查它的类型(因为Hibernate检测到方言):
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");
}
});
}
注意,可以按照您想要的方式更改方法体(检查JDBC URL,检查驱动程序名称,检查几乎所有内容)。
编辑:上面的方法适用于hibernate 3.5 +。
对于Hibernate早期版本(例如3.2),它可能更容易:
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");
}
答案 1 :(得分:2)
如果它是AbstractTransactionalDataSourceSpringContextTests
的子类,那么你试过吗?
getJdbcTemplate().getDataSource()
?
否则你可以尝试
((SessionImplementor) session).getJdbcConnectionAccess().obtainConnection()
.getMetaData().getDatabaseProductName()
但这有点令人作呕。 :)似乎在Hibernate 4.x中引入了。
在旧版本中使用现已弃用的:
((SessionImpl) session).getSessionFactory().getConnectionProvider()
.getConnection().getMetaData().getDatabaseProductName();
答案 2 :(得分:1)
这是完全黑客攻击,可能无法正常工作,因为您需要转换为您的设置可能未使用的特定类。
SessionFactoryImpl factory = (SessionFactoryImpl) session.getSessionFactory(); // or directly cast the sessionFactory
DatasourceConnectionProviderImpl provider = (DatasourceConnectionProviderImpl)factory.getConnectionProvider();
DataSource dataSource = provider.getDataSource();
factory.getConnectionProvider()
返回可以实现by any number of classes的ConnectionProvider
(接口)实例。其中一个是DatasourceConnectionProviderImpl
,您可以使用它来获取数据源。
DatasourceConnectionProviderImpl
应该是默认值,除非您使用的是休眠C3P0或Proxool池。
答案 3 :(得分:0)
如果要在不打开新连接的情况下检测数据库提供程序,您可能会发现使用方言类很有用。
String dialectName = ((SessionFactoryImplementor)sessionFactory).getDialect().getClass().getSimpleName().toLowerCase();
if(dialectName.contains("oracle"))
...
else if(dialectName.contains("mysql"))
...