Spring boot hibernate no transaction is in progress
I don't quite understand why you're making your service method so unnecessarily complex. You should simply be able to do it this way
@Transactional
public void insertUser(User user) {
entityManager.persist( user );
}
If there are points where you need access to the native Hibernate Session
you can simply unwrap and use the Session
directly like this:
@Transactional
public void doSomethingFancyWithASession() {
Session session = entityManager.unwrap( Session.class );
// use session as needed
}
The notion here is that Spring provides you an already functional EntityManager
instance by you using the @PersistenceContext
annotation. That instance will safely be usable by the current thread your spring bean is being executed within.
Secondly, by using @Transactional
, this causes Spring's transaction management to automatically make sure that the EntityManager
is bound to a transaction, whether that is a RESOURCE_LOCAL
or JTA
transaction is based on your environment configuration.
You're running into your problem because of the call to #getCurrentSession()
.
What is happening is Spring creates the EntityManager
, then inside your method when you make the call to #getCurrentSession()
, you're asking Hibernate to create a second session that is not bound to the transaction started by your @Transactional
annotation. In short its essentially akin to the following:
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
Session aNewSession = entityManager.unwrap( Session.class )
.getFactory()
.getCurrentSession();
// at this point entityManager is scoped to a transaction
// aNewSession is not scoped to any transaction
// this also likely uses 2 connections to the database which is a waste
So follow the paradigm I mention above and you should no longer run into the problem. You should never need to call #getCurrentSession()
or #openSession()
in a Spring environment if you're properly allowing Spring to inject your EntityManager
instance for you.