7

我有几个应该使用 HSQLDB 的单元测试,但我知道其中一些实际上是在访问物理数据库。我想在测试中添加一个检查,以确保正在使用的 DataSource 用于 HSQLDB 而不是 live DB。

从休眠会话对象(org.hibernate.classic.Session),我如何检查数据源

更新: 我还可以访问会话工厂 ( org.hibernate.impl.SessionFactory)。

详细信息:休眠 3.2

4

4 回答 4

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,检查驱动程序名称,检查几乎所有内容)。

编辑:上面的方法适用于休眠 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");
}
于 2013-03-15T21:12:40.580 回答
3

如果它是 的子类AbstractTransactionalDataSourceSpringContextTests,那么您尝试过 getJdbcTemplate().getDataSource()吗?

否则你可以试试

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

但这有点恶心。:) 并且似乎在 Hibernate 4.x 中引入。

编辑:

在旧版本上使用现已弃用的:

    ((SessionImpl) session).getSessionFactory().getConnectionProvider()
                           .getConnection().getMetaData().getDatabaseProductName();
于 2013-03-15T20:46:53.370 回答
1

这完全是一个技巧,可能不起作用,因为您需要转换为您的设置可能未使用的特定类。

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

factory.getConnectionProvider()返回ConnectionProvider可以由任意数量的类实现的(接口)实例。其中之一是DatasourceConnectionProviderImpl,然后您可以使用它来获取数据源。

DatasourceConnectionProviderImpl应该是默认值,除非您使用的是休眠 C3P0 或 Proxool 池。

于 2013-03-15T21:06:22.737 回答
0

如果您想在不打开新连接的情况下检测数据库提供者,您可能会发现使用方言类很有用。

    String dialectName = ((SessionFactoryImplementor)sessionFactory).getDialect().getClass().getSimpleName().toLowerCase();
    if(dialectName.contains("oracle"))
        ...
    else if(dialectName.contains("mysql"))
        ...
于 2015-11-25T13:12:17.143 回答