【问题标题】:EntityManagerFactory.close() not closing HikariDataSource set by hibernate.connection.datasource-propertyEntityManagerFactory.close() 不关闭 hibernate.connection.datasource-property 设置的 HikariDataSource
【发布时间】:2020-08-12 09:16:39
【问题描述】:

我正在使用 Hibernate 5.4.18 和 HikariCP 3.4.5。我的配置是程序化的,我用hibernate.connection.datasource-property 设置了 Hibernate 的底层数据源。奇怪的是,当我调用EntityManagerFactory.close()-function 时,它并没有调用 HikariDataSource 的close()-method,连接将保持打开状态。这是理想的行为吗? Oracle 文档说EntityManagerFactory.close() 将“关闭工厂,释放它拥有的所有资源”。

Kotlin 的最小示例:

fun main() {
    val emf = Persistence.createEntityManagerFactory("default", getJpaProperties())
    // Fetch underlying HikariDataSource
    val ds = emf.unwrap(SessionFactoryImpl::class.java)
        .serviceRegistry
        .getService<ConnectionProvider>(ConnectionProvider::class.java)
        .unwrap(HikariDataSource::class.java)
    emf.close()
    println(ds.isClosed) // prints "false"
}

private fun getJpaProperties(): Map<String, Any> {
    val dataSource = HikariDataSource().apply {
        username = "sa"
        password = ""
        jdbcUrl = "jdbc:h2:mem:test_db"
    }
    return mapOf(
        "hibernate.dialect" to "org.hibernate.dialect.H2Dialect",
        "hibernate.connection.datasource" to dataSource
    )
}

【问题讨论】:

    标签: java hibernate kotlin jpa hikaricp


    【解决方案1】:

    这是因为您提供了一个数据源的实例。如果您初始化一个 DS,那么您很有可能会在代码的其他部分使用它,因此关闭数据源会引入意外行为。这实际上是一个很好的做法,创建资源的“模块”也负责处理它。

    如果您提供数据源的详细信息(用户名、密码、类名等),Hibernate 将关闭数据源,因为它将由 Hibernate 管理。

    从历史上看,在过去,DS 将由 J2EE 容器(例如 Tomcat)在其中创建,然后在该容器内的许多应用程序之间共享。属性hibernate.connection.datasource 将是指向数据源的 JNDI 位置。

    【讨论】:

    • 听起来很合乎逻辑,虽然我认为这很容易错过和泄漏资源。
    猜你喜欢
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    相关资源
    最近更新 更多