I am sure that among Spring/Hibernate developers, there are a lot confuses about the concepts of JPA transaction, Hibernate sessions and JDBC connections and even DB transactions, sometimes these kind of confuses can impact the application design and issues investigation, so let’s make some clarification about these concepts.
Here is the high level relationship diagram:
EntityManager plays as a center role inside the whole JPA process, and Session is a critical component for Hibernate to implement the JPA infrastructure.
EntityManger And Transaction
Application modules call the EntityManager to fetch and manage entities within the entity persistent context, it uses TransactionManager to open and manage transaction, the operations that performed through EntityManager are placed within some JPA transaction to implement the business and DB operation transaction management.
How To Build Transaction
You can always manually build and manage transaction manually, you need build EntityManager instance and then create a transaction by calling getTransaction, and declare the context of a transaction by putting the business logic between begin and commit calls.
Spring has some other classes to help better manually declare and manage JTA transaction like TransactionTemplate.
Spring has extended the JPA/JTA support above Hibernate, it introduced @Transactional annotation onto Java class or method to declare JTA transaction, under the hood, Spring uses interceptor to automatically wraps the Java business logic into JTA transaction.
Transaction Is Not Mandatory
You do not have to create transaction to use JPA EntityManager and underlying Hibernate Session, if you just perform readonly Hibernate calls and without lock on entities, transaction is not necessary. However, most other write operation involved EntityManager calls ask for transaction to be provided, otherwise there will be some TransactionRequiredException thrown out.
Although transaction is not mandatory, yet it is recommended, transaction can help better manage validity of business performing and efficiently manage resource when failures or exceptions happen. Especially for application managed entity context, we should be very careful on managing the resource underlying. So that is why transaction is always recommended. You do not want the Hibernate session and underlying JDBC connection kept being opened when exception happens or the application logic is done.
To make sure EntityManager can be closed always and the according Hibernate resource can be deallocated, Spring introduce some extended function to enforce transaction to all DB operations including readonly query operation.
JPA Transaction Is Not DB Transaction
JPA Transaction is not DB transaction or more actually speaking, it is not DB transaction only, it can be used to manage any transaction resources besides database. It supports more complicated transaction concepts like join and detach etc. Spring categories transactions into global and local modes, global transaction is an application server managed transaction, local Transaction is resource specific transaction. So do not always expect the JPA transaction can always involves DB transaction, or do not think JPA transaction always matches some DB transaction. You better not connect the two concepts.
EntityManager And Hibernate Session
Hibernate Session internally implements the EntityManager calls from application modules, it actually plays as an isolation layer between JDBC connection and EntityManager.
When Hibernate Session Is Created
A Session is created on demand, it is created first time when EntityManager calls getSession method.
When Hibernate Session Is Closed
Hibernate dose not enforce a Session t be closed even it recommends that Session’s lifecycle should begin with transaction start and end after transaction completes, you can actually keep using a same Session for multiple EntityManager calls, even across transactions.
However, for use the resource more efficiently, Spring JPA support always close a Session through closing EntityManager either at the completion or at the rollback of transaction.
Hibernate Session And JDBC Connection
Hibernate uses TransactionCoordinator as some coordinator between Hibernate engine (Session) with the physical transactions (connections), so you can see that inside Hibernate, transaction actually means physical connection. Hibernate puts both connection and transaction into the TransactionCoordinator so that Session can easily grab the coordinator to manage connections or transactions around them.
JdbcCoordinator is abstracted with all JDBC related activities.
LogicalConnection defines the contract with logic connection and handles physical JDBC connection internally.