I am creating the session factory by myself (not via Spring infra) - see minimal working example below. I am using Hibernate 6.4.4.
I think I need to somehow provide it an transaction manager (HibernateTransactionManager?), so it can use it then in the beginTransaction, but how?
@Test
fun insertViaEntityManagerFails() {
val metadata = ensureSchema(MyEntity::class.java)
val sessionFactory = metadata.buildSessionFactory()
sessionFactory.openSession().use {
val t = it.beginTransaction()
val em = it.entityManagerFactory.createEntityManager()
em.persist(MyEntity(id = 777))
em.flush() // This throws 'no transaction is in progress' (does not matter whether I call beginTransaction() or not)
t.commit()
}
}
@Test
fun insertViaStateLessSessionWorks() {
val metadata = ensureSchema(MyEntity::class.java)
val sessionFactory = metadata.buildSessionFactory()
sessionFactory.openStatelessSession().use {
it.insert(MyEntity(id = 1234))
}
// This works and the entity is inserted correctly
}
private val dataSource = DataSourceBuilder... // Db connection here
private fun createMetadata(classes: Array<out Class<*>>): Metadata {
val registry = StandardServiceRegistryBuilder().applySettings(
mapOf("hibernate.connection.datasource" to dataSource)
).build()
return MetadataSources(registry).addAnnotatedClasses(*classes).metadataBuilder.build()
}
private fun ensureSchema(vararg classes: Class<*>): Metadata {
val metadata = createMetadata(batchSize, classes)
val schemaUpdate = SchemaExport()
schemaUpdate.execute(EnumSet.of(TargetType.DATABASE), SchemaExport.Action.BOTH, metadata)
if (schemaUpdate.exceptions.isNotEmpty()) {
throw Exception("Schema update failed")
}
return metadata
}