3.7. Automatic state detection
The merge operation is clever enough to automatically detect whether the merging of the detached instance has to result in an insert or update. In other words, you don't have to worry about passing a new instance (and not a detached instance) to
merge()
, the entity manager will figure this out for you:
// In the first entity manager Cat cat = firstEntityManager.find(Cat.class, catID); // In a higher layer of the application, detached Cat mate = new Cat(); cat.setMate(mate); // Later, in a new entity manager secondEntityManager.merge(cat); // update existing state secondEntityManager.merge(mate); // save the new instance
The usage and semantics of
merge()
seems to be confusing for new users. Firstly, as long as you are not trying to use object state loaded in one entity manager in another new entity manager, you should not need to use merge()
at all. Some whole applications will never use this method.
Usually
merge()
is used in the following scenario:
- the application loads an object in the first entity manager
- the object is passed up to the presentation layer
- some modifications are made to the object
- the object is passed back down to the business logic layer
- the application persists these modifications by calling
merge()
in a second entity manager
Here is the exact semantic of
merge()
:
- if there is a managed instance with the same identifier currently associated with the persistence context, copy the state of the given object onto the managed instance
- if there is no managed instance currently associated with the persistence context, try to load it from the database, or create a new managed instance
- the managed instance is returned
- the given instance does not become associated with the persistence context, it remains detached and is usually discarded
Note
Merging in EJB3 is similar to the
saveOrUpdateCopy()
method in native Hibernate. However, it is not the same as the saveOrUpdate()
method, the given instance is not reattached with the persistence context, but a managed instance is returned by the merge()
method.