Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does hibernate do the SELECT before SAVE?

Why does hibernate do a select before saving an object?

I can't find useful information on internet. Is this normal behavior before every save? I found this topic, select Query Run for hibernateTemplate.save() - save, but I do not find this answer "definitive". I mean, do we have to use versioning if i want to avoid this select before saving each object?

I would appreciate all the explanations or links.

like image 259
Julia Avatar asked Apr 08 '11 05:04

Julia


People also ask

How Save method works in hibernate?

Hibernate save method returns the generated id immediately, this is possible because primary object is saved as soon as save method is invoked. If there are other objects mapped from the primary object, they gets saved at the time of committing transaction or when we flush the session.

What is save and update method in hibernate?

The save() method INSERTs an object in the database. It will persist the given transient instance, first assigning a generated identifier. It returns the id of the entity created. The saveOrUpdate() calls either save() or update() on the basis of identifier exists or not.

How does Hibernate know to persist data passed to the entity class via a setter?

The mechanism Hibernate use to generate query is call dirty checking. By default once you load an record from the database Hibernate will store a snapshot of the entity in the persistence context and give you a managed entity.

Which method in Hibernate JPA is used for updating a record in the database?

The main intention of the merge method is to update a persistent entity instance with new field values from a detached entity instance.


3 Answers

So Julia is right, calling Session.save() with an entity that has its IDs assigned results in hibernate doing a SELECT and then an INSERT. Fortunately there are two workarounds:

  • Don't assign your IDs up front (wasn't an option for me)
  • Call Session.persist() rather than Session.save()

The second option also works seamlessly with Envers.

Hope this saves someone else hours of hunting.

like image 135
ifx Avatar answered Oct 20 '22 11:10

ifx


I know you have answered your own question in the question's comment, but just to summarise this here are some general points.

Just to clarify, NHibernate uses 'save' as in 'SQL INSERT' and 'update' as in 'SQL UPDATE'.

I know of these common scenarios when NHibernate will fetch an object implicitly (no explicit use of s.Update) from the db before persisting it:

  1. On session_flush/transaction_commit (depending on settings) when in the mapping select-before-update is set to "true";
  2. When SaveOrUpdate is used and the identifier of the instance has a value which suggests it exists in the db;
  3. Before s.Delete.

As with your example, this may not be obvious when parent-child objects are used (but simple rules stay the same) as it may not be obvious from the code that children will be fetched.

like image 2
tymtam Avatar answered Oct 20 '22 10:10

tymtam


No, it doesn't do a select before a save. Are you sure your edit-save usecase is right? A common flow for webapps is:

  • user clicks (GET) on /products/5/edit
  • server fetches Product#5 into the http session
  • server returns the html form for editing Product#5
  • user submits (POST) form
  • server grabs Product#5 from http session
  • server populates it from request
  • server merges populated Product#5 back to the hibernate

A single sql update will be executed which also handles versioning. If the version number is out of sync, a StaleObjectStateException will be thrown.

like image 1
cherouvim Avatar answered Oct 20 '22 11:10

cherouvim