簡體   English   中英

如何確定Hibernate會話正在使用的DataSource?

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

我有幾個應該使用HSQLDB的單元測試,但我知道其中一些實際上正在使用物理數據庫。 我想在測試中添加一個檢查,以確保正在使用的DataSource用於HSQLDB,而不是實時DB。

從hibernate會話對象( org.hibernate.classic.Session ),我如何檢查DataSource

更新:我還可以訪問會話工廠( org.hibernate.impl.SessionFactory )。

詳細信息: Hibernate 3.2

無論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");
}

如果它是AbstractTransactionalDataSourceSpringContextTests的子類,那么你試過getJdbcTemplate().getDataSource()嗎?

否則你可以試試

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

但這有點令人作嘔。 :)似乎在Hibernate 4.x中引入了。

編輯:

在舊版本上使用現已棄用的:

    ((SessionImpl) session).getSessionFactory().getConnectionProvider()
                           .getConnection().getMetaData().getDatabaseProductName();

這是一個徹底的黑客,可能無法工作,因為您需要轉換為您的設置可能沒有使用的特定類。

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

factory.getConnectionProvider()返回一個可由任意數量的類實現的ConnectionProvider (接口)實例。 其中之一是DatasourceConnectionProviderImpl ,您可以使用它來獲取數據源。

除非您使用的是休眠C3P0或Proxool池,否則DatasourceConnectionProviderImpl應該是默認值。

如果要在不打開新連接的情況下檢測數據庫提供程序,您可能會發現使用方言類很有用。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM