hibernate envers: merge & saveOrUpdate

2019-02-11 01:21发布

问题:

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.

回答1:

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.



回答2:

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.