I think I've found the answer myself. If somebody finds this question, here's my answer.
How does Spring manage Hibernate Sessions?
By default, Spring Boot applies transaction management at the repository level. In this case, when calling a JpaRepository
method (or in general any Repository
method), Spring will:
- Ask the
SessionFactory
to create a new session
- Open this session
- Open a transaction
- Perform the called
Repository
method
- Close the transaction
- Close the session
However, if you apply @Transactional
to the service class or method, Spring will open the session and the transaction on entry to the service method, and the repository method will be performed within the existing transaction.
What are the consequences?
As a programmer...
- you do not need to concern yourself with transactions or sessions at all.
- if you want to rely on Hibernate's caching functionality, you must specify
@Transactional
on a larger scope than the repository. Caching only works within the same HibernateSession
.
- you must decide the equivalence of your
@Entity
objects by their Hibernate ID value, rather than by using Java's ==
operator.
- you need to take care that lazy collections (for example in an
@OneToMany
reference) in your @Entity
classes (see FetchMode.LAZY
as opposed to FetchMode.EAGER
) are used exclusively within an @Transactional
-annotated method
Also for reference, the following link has been quite helpful: Multiple Transactions in single session
As with many other aspects of Spring, there is a lot to be gained here, if you are willing to sacrifice direct control over your application.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…