Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate : Downside of merge() over update()

I'm having problems with a NonUniqueObjectException thrown by Hibernate.

Reading the docs, and this blog post, I replaced the call from update() to merge(), and it solved the problem.

I believe I understand the reason for the exception, and why changing the method fixed the problem, in terms of disconnected objects and session boundaries.

My question is : given that merge() will always resolve to the session object, or retrieve it if it doesn't exist, is calling merge() generally a safer alternative than update()?

What is the downside of using merge() over update()?

like image 837
Marty Pitt Avatar asked Jan 22 '10 15:01

Marty Pitt


People also ask

What is difference between merge () and update () methods in Hibernate?

Hibernate handles persisting any changes to objects in the session when the session is flushed. update can fail if an instance of the object is already in the session. Merge should be used in that case. It merges the changes of the detached object with an object in the session, if it exists.

What is the difference between Merge and persist in Hibernate?

Persist should be called only on new entities, while merge is meant to reattach detached entities. If you're using the assigned generator, using merge instead of persist can cause a redundant SQL statement.

What is the use of merge in Hibernate?

Hibernate merge can be used to update existing values, however this method create a copy from the passed entity object and return it. The returned object is part of persistent context and tracked for any changes, passed object is not tracked. This is the major difference with merge() from all other methods.

Does merge operation creates new copy of entity object?

Merge returns the managed instance that the state was merged with. It does return something that exists in PersistenceContext or creates a new instance of your entity. In any case, it will copy the state from the supplied entity, and return a managed copy.


1 Answers

Is calling merge() generally a safer alternative than update() ?

As a way to avoid NonUniqueObjectException, yes. I think it explains why JPA does not allow an update method.

What is the downside of using merge() over update() ?

An unadvised user may think he or she has a fresh managed entity. Something like

// myEntity (passed as parameter does not become managed) // Only the one returned by the merge operation is a managed entity session.merge(myEntity);  // "newValue" is not commited because myEntity is not managed myEntity.setMyProperty("newValue"); 

And if your persistence context does not contain your entity, maybe you do not want select-before-updating default behavior. But it can be avoided

  • Add a version (@Version) column. 0 or NULL version indicates that an instance is new and has to be inserted, not updated
  • Use a Hibernate interceptor
  • If you are sure you want to update instead of inserting, you can use the following approach

...

public void updateMyEntity(MyEntity updateableMyEntity);      // load does not hit the database     MyEntity myEntity = (MyEntity) session.load(MyEntity.class, updateableMyEntity.getId());      BeanUtils.copyProperties(myEntity, updateableMyEntity);  } 

This way you can update your entity without merge or update method. See this question for more information: Best way to update some fields of a detached object on Hibernate ?

like image 180
Arthur Ronald Avatar answered Sep 23 '22 09:09

Arthur Ronald