3

I am working on an spring-hibernate-envers application. After lot of googling things are finally working for me but i have still got couple of questions.

  1. Earlier i was using saveOrUpdate for saving or updating entities. But when working with envers it was throwing a nonUniqueObject exception. So i used merge instead and it worked. Is it right to use merge for this? Does merge inserts new objects to db?

  2. I tried following code:

entity=merge(entity);  
saveOrUpdate(entity);

This also worked. Is it the right way? And also i am curious that why saveOrUpdate is not throwing any error now.

skaffman
  • 398,947
  • 96
  • 818
  • 769
parbi
  • 533
  • 1
  • 10
  • 19

2 Answers2

10

Hibernate Reference says:

saveOrUpdate() does the following:

  • if the object is already persistent in this session, do nothing
  • if another object associated with the session has the same identifier, throw an exception
  • if the object has no identifier property, save() it
  • if the object's identifier has the value assigned to a newly instantiated object, save() it
  • if the object is versioned by a or , and the version property value is the same value assigned to a newly instantiated object, save() it
  • otherwise update() the object

and merge() is very different:

  • if there is a persistent instance with the same identifier currently associated with the session, copy the state of the given object onto the persistent instance
  • if there is no persistent instance currently associated with the session, try to load it from the database, or create a new persistent instance
  • the persistent instance is returned
  • the given instance does not become associated with the session, it remains detached

It means that you can use saveOrUpdate() if you are sure that the object with the same identifier is not associated with the session. Otherwise you should use merge().

The following code

entity=merge(entity);
saveOrUpdate(entity); 

works because the result of merge() is a persistent object, therefore it's ignored by saveOrUpdate(), so that the second line doesn't make any sense.

Community
  • 1
  • 1
axtavt
  • 239,438
  • 41
  • 511
  • 482
  • ok, so if i am not sure that an object with the same id may be associated with the session, i should go with merge. As you have already mentioned merge also inserts new object to db, there should be no problem. Also does merge takes more resources then saveOrUpdate? Thanks for your answer. – parbi Mar 15 '11 at 13:12
  • 1
    @parbi: Compared to `saveOrUpdate`, `merge` generates one extra SQL query since `saveUpdate` uses identifier to determine whether object should be saved, whereas `merge` checks it against the database. – axtavt Mar 15 '11 at 13:30
  • Are you sure about this statement : the result of merge() is a persistent object, therefore it's ignored by saveOrUpdate() so that the second line doesn't make any sense ?? As stated in your answer, the object is still detached after a merge – fabien7474 Sep 22 '11 at 06:54
  • 1
    @fabien7474: The object returned from `merge()` is persistent, whereas the object passed to it remains detached. – axtavt Sep 22 '11 at 09:38
  • @axtavt: The observation you made about `merge()` in previous comment is brilliant, helped me solve my problem +1 :D – Răzvan Flavius Panda Jan 04 '13 at 17:17
0

saveOrUpdate: If requested object is transient(null primary key value) then, persist it in database or update it. The condition is that there is only one copy of that entity in session.

merge: Hibernate will first check whether a Persistent instance of that type already exists in the persistent context. It uses the object identifiers to check on this existence. If another instance exists, it copies the state of the Detached object into the existing Persistence object. If no other instance exists, Hibernate just reattaches the Detached object.

If the session contains more then one copy of a single entity, then update all the copy with latest entity. It will not update in database until you call update.

Nikunj
  • 3,100
  • 2
  • 20
  • 19