Hibernate Merge and Persist



Persist and merge are for two different purposes (they aren't alternatives at all).

(edited to expand differences information)

persist:

Insert a new register to the database
Attach the object to the entity manager.

merge:

Find an attached object with the same id and update it.
If exists update and return the already attached object.
If doesn't exist insert the new register to the database.

persist() efficiency:

It could be more efficient for inserting a new register to a database than merge().
It doesn't duplicates the original object.

persist() semantics:

It makes sure that you are inserting and not updating by mistake.

Example:

{
    AnyEntity newEntity;
    AnyEntity nonAttachedEntity;
    AnyEntity attachedEntity;

    // Create a new entity and persist it        
    newEntity = new AnyEntity();
    em.persist(newEntity);

    // Save 1 to the database at next flush
    newEntity.setValue(1);

    // Create a new entity with the same Id than the persisted one.
    AnyEntity nonAttachedEntity = new AnyEntity();
    nonAttachedEntity.setId(newEntity.getId());

    // Save 2 to the database at next flush instead of 1!!!
    nonAttachedEntity.setValue(2);
    attachedEntity = em.merge(nonAttachedEntity);

    // This condition returns true
    // merge has found the already attached object (newEntity) and returns it.
    if(attachedEntity==newEntity) {
            System.out.print("They are the same object!");
    }

    // Set 3 to value
    attachedEntity.setValue(3);
    // Really, now both are the same object. Prints 3
    System.out.println(newEntity.getValue());

    // Modify the un attached object has no effect to the entity manager
    // nor to the other objects
    nonAttachedEntity.setValue(42);
}

This way only exists 1 attached object for any register in the entity manager.

merge() for an entity with an id is something like:

AnyEntity myMerge(AnyEntity entityToSave) {
    AnyEntity attached = em.find(AnyEntity.class, entityToSave.getId());
    if(attached==null) {
            attached = new AnyEntity();
            em.persist(attached);
    }
    BeanUtils.copyProperties(attached, entityToSave);

    return attached;
}

Although if connected to MySQL merge() could be as efficient as persist() using a call to INSERT with ON DUPLICATE KEY UPDATE option, JPA is a very high level programming and you can't assume this is going to be the case everywhere.


Source:Stackoverflow

Comments

Popular posts from this blog

How SQL Indexes Work internally ?

UML,HLD and LLD.

Mutable and Immutable Objects