EntityManager is the probably the most important class you need to know when writing your JPA data layer. In some way, you can think of EntityManager like your nice trustworthy dentist. The very first time you go to your dentist, he doesn’t know anything about you, so you’ll have to register and fill in a form. Once your dentist has finished filling that hole in your tooth, he’ll probably note couple things in your patient record and file it. You would then go home, your dentist wouldn’t know what you are doing afterwards and in few weeks when you came back he would ask if any of your medical condition had changed since and update the record.
The way JPA EntityManager work is quite similar. Following is a picture of various states a JPA entity can be, and method that transitions from one state into another.
When a new entity object is created in the java memory, the entity manager had no idea about it. This entity object is called to be in new (transient) state. Entity manager wouldn’t care with whatever change you made to the object.
When you call the entity manager’s persist() method over the object, it saves the state of the object into the persistent storage (typically database), and starts to care about changes you make to it. The entity object is now in managed state. If you modify the state of the object, entity manager will synchronize the state back to the persistent storage. Synchronizing state back into persistent storage typically means issuing necessary SQL statement so the state of the object matches the ones on the database. Entity manager will not issue SQL statement immediately all the time, but only at “flush time”.
The specifics of when entity manager performs flushing differs between various JPA implementation, but here is what Hibernate documentation says:
Flush occurs by default (this is Hibernate specific and not defined by the specification) at the following points:
- before query execution
- from javax.persistence.EntityTransaction.commit()
- when EntityManager.flush() is called
It’s also pretty common for the entity object to lose contact with entity manager even after it’s managed. This typically happen when the entity manager is closed, or the object leaves the java memory (eg being transferred to a web browser screen). An entity object which was once persistence but no longer is is called to be in detached state.
An object which is in detached state can be put back into managed state by calling merge() method. Entity manager will typically try to identify the object by its primary key, and perform DML statements such as UPDATE to synchronize the persistent state.
If a lot of changes need to be done to the object’s state, a common technique is to do this while the object is in detached state, and then reattach it later, thus we can avoid costs of issuing SQL statement during the changes.
Finally an entity object in managed state can be marked for removal, and this object is called to be in removed state.
Chapter 3 of Hibernate Entity Manager documentation is a good reading if you want to learn more about JPA state.