What is Persistence Context?
The Persistence Context is a set of managed entity instances whose purpose is to synchronize entity state with the database. As a cache managed by the EntityManager, it minimizes the number of database hits by tracking changes throughout a transaction. Like a write-behind cache, these updates are only sent to the database at transaction commit:
In this scenario, the em.find()
inspects the Persistence Context before querying the database. And transaction.commit()
triggers the flush operation where the DB gets updated, keeping the book
instance up-to-date.
EntityManager and its Factory
EntityManager is your gateway to the Persistence Context. Its role is to manage entity life-cycle, typically involving creation and deletion of entities, finding entities, and running queries.
EntityManagerFactory, thoroughly heavy, creates EntityManager instances. Conventionally, it's made once when the application boots:
Entity lifecycle: Birth to Death
Every entity in the Persistence Context has a lifecycle:
- New/Transient: Entity just got created. It's new in the town, yet to be recognized.
- Managed: Entity got street cred. It's now under the Persistence Context's surveillance.
- Detached: Entity is on vacation. The Persistence Context no longer babysits it.
- Removed: Entity is remembered in memories. It‘s scheduled to be extinct from the database on transaction commit.
First-level cache: Your secret weapon
The built-in first-level cache of the Persistence Context preempts the need to hit the database every time data is needed. If an entity is already in the cache, no expensive database call is made:
Flushing: The unseen hero
Flush, in Persistence Context terms, is a forced synchronization of the cache state with the database. If you were to update an entity within a transaction, those changes won't hit the database immediately. Instead, the updates are flushed—sent to the database all at once when the transaction commits:
Concurrency control: Chaos manager
Ever wondered how to manage concurrency? The Persistence Context can help by minimizing the duration of possible conflicting updates using optimistic locking. This approach, combined with managing the lifecycle of entities, is an effective way to address concurrent data access.
Entity reattachment: Detach, relax, and merge
An entity may get detached when its Persistence Context closes or it's explicitly evicted. Fear not, you can merge it and sync its state with the latest data in the database:
CRUD operations: Make the loop
The Persistence Context ropes in CRUD operations: Create, Read, Update, and Delete. Here's probably how your usual interaction with an entity looks like:
- Create:
persist(entity)
- Read:
find(entityClass, primaryKey)
orcreateQuery()
- Update: Just modify a managed entity. It's a different world here
- Delete:
remove(entity)
Was this article helpful?