Hibernate Saveorupdate Behavior

Hibernate saveOrUpdate behavior

When you use .saveOrUpdate() Hibernate will check if the object is transient (it has no identifier property) and if so it will make it persistent by generating it the identifier and assigning it to session. If the object has an identifier already it will perform .update().

From the documentation:

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
    "version" or "timestamp", and the
    version property value is the same
    value assigned to a newly
    instantiated object, save() it
    otherwise update() the object

How Hibernate SaveOrUpdate(beanobject) method identifies that the given beanobject exist or not

As of I know, hibernate Session will get identify the object based on the Primary Key column. Let's say for example, ID is the primary key column in a table and you have set some value to the ID parameter of passing object. Session will check in the mapped table ID value exist or not. If exists, it will call the update(object) otherwise save(object) methods accordingly.

For more information refer this documentation link.

There is a way to check if Hibernate method .saveOrUpdate() did an insert or update?

Yes, Checking the Identifier associated with an entity in the persistence context means we are checking if the entity is in persistent state or not.
Since u have already referred the documentation i would suggest please have look at this question,
Hibernate saveOrUpdate behavior - have a look at Olaf's answer, it explains how it works in short and sweet way.

with JPA 2.0 we have the

Object id = entityManagerFactory.getPersistenceUnitUtil().getIdentifier(entity); way of checking.

However your question is tagged for hibernate, so the first one is correct.

Serializable id = session.getIdentifier(entity);

Different behavior of hibernate merge, and saveOrUpdate

You must have @ManyToOne(cascade=CascadeType.MERGE) (at least) for that to work (or the relevant xml mapping)

This instructs hibernate to cascade merge operations to this particular relation - i.e. when the parent object (item) is merged, also merge the child (category). Maybe you have omitted the MERGE cascade type, and that's why saveOrUpdate works.

How to avoid saveOrUpdate on all the columns hibernate

Hibernate does exactly what you tell it to do: you ask it to update a Login, this Login's userName and password are null, so it updates the Login and sets userName and password to null. It can't guess that you actually want to update songs of an existing Login object, unless you tell it to do that:

Login existingLogin = (Login) session.get(Login.class, userId);
existingLogin.addSong(song);

That code does what you want to do: add a Song to an existing Login object, which already has a userId, a userName and a password, which should stay as they are.

use of update or saveorupdate method in hibernate

why the update or saveOrUpdate method are needed?

The second part of your question answers the first part: the methods are used to update a detached object, whose state is not tracked by Hibernate.

why do update and saveOrUpdate method throw exception if we try to save detached object and that object is associated with session?

Because Hibernate provides a guarantee (that is crucial to its own correct behavior): inside a session, there can only be one instance of a given entity. Since update() and saveOrUpdate() take a detached entity and make it attached, if there is already an attached version of that entity in the session and Hibernate didn't throw an exception, you would end up with two attached instances of the same entity in the same session. And that would thus break the Hibernate guarantee. What would happen if user1 and user2 were two attached instances of the User with ID 42:

user1.setName("Foo");
user2.setName("Bar");

Now you commit the transaction: what should be the name of the user?



Related Topics



Leave a reply



Submit