Reputation: 452
I'm using Hibernate 5.4.18 with HikariCP 3.4.5. My configuration is programmatic, and I set underlying DataSource of Hibernate with hibernate.connection.datasource
-property. Strangely, when I then call EntityManagerFactory.close()
-function, it doesn't call close()
-method of HikariDataSource, and connection will leave open. Is this a desired behavior? Oracle documentation says that EntityManagerFactory.close()
will "Close the factory, releasing any resources that it holds".
Minimum example with 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
)
}
Upvotes: 0
Views: 317
Reputation: 29977
It's because you are providing an instance of a datasource. If you initialise a DS, there's a big chance you'll use it in other parts of your code, so closing the datasource would introduce an unexpected behaviour. This is actually a good practice, that the "module" that creates a resource is also responsible for disposing of it.
Hibernate will close the datasource if you provide the details of it (username, password, class name, etc), as it will be managed by Hibernate.
For a bit of history, in the old days, a DS would be created in by a J2EE container (e.g. Tomcat) and then shared across many apps inside that container. And the property hibernate.connection.datasource
would be a JNDI location pointing to the datasource.
Upvotes: 1