Julia
Julia

Reputation: 1237

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.

Upvotes: 10

Views: 13776

Answers (3)

ifx
ifx

Reputation: 581

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.

Upvotes: 5

tmaj
tmaj

Reputation: 35075

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.

Upvotes: 2

cherouvim
cherouvim

Reputation: 31903

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.

Upvotes: 0

Related Questions