0

I have Fluent NHibernate set up in my ASP.NET MVC Project. For most of my records, I need to explicitly call Repository.Update(record) for the record to actually be persisted into the database.

I was playing around with my project, and I found out that one of my objects was persisting its information into the database without me calling Update. I thought that it was because I had called Update later on in the code, but that wasn't the case. I changed one of the fields in my object one line before I returned the View.

I set a breakpoint at Update (at the line before returning the view), and it never went there... If it makes a difference, I did call Update explicitly about 10 lines before.

I know this is a little vague since there's a ton of configuration and customization involved. I was just hoping for a nudge in the right direction or where to look.

Player myPlayer = this.PlayerRepository.GetById(id); 
myPlayer.Location = "USA"; 
myPlayer.Age = 19;
this.PlayerRepository.Update(myPlayer);
...
...
...
myPlayer.Name = "John";   //this is being persisted without me actually calling Update
return View; 
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
mute
  • 311
  • 1
  • 3
  • 14

1 Answers1

2

This would most likely be duplicate:

Small cite from this Q & A

Hibernate maintains a cache of Objects that have been inserted, updated or deleted. It also maintains a cache of Objects that have been queried from the database. These Objects are referred to as persistent Objects as long as the EntityManager that was used to fetch them is still active. What this means is that any changes to these Objects within the bounds of a transaction are automatically persisted when the transaction is committed. These updates are implicit within the boundary of the transaction and you don’t have to explicitly call any method to persist the values.

Simply, what you experience, it is a standard, correct behaviour. That's how the ORM tools usually works.Try to read about:

9.6. Flush

From time to time the ISession will execute the SQL statements needed to synchronize the ADO.NET connection's state with the state of objects held in memory. This process, flush, occurs by default at the following points

  • from some invocations of Find() or Enumerable()

  • from NHibernate.ITransaction.Commit()

  • from ISession.Flush()

The SQL statements are issued in the following order

  • all entity insertions, in the same order the corresponding objects were saved using ISession.Save()

  • all entity updates

  • all collection deletions

  • all collection element deletions, updates and insertions

  • all collection insertions

  • all entity deletions, in the same order the corresponding objects were deleted using ISession.Delete()

(An exception is that objects using native ID generation are inserted when they are saved.)

Except when you explicity Flush(), there are absolutely no guarantees about when the Session executes the ADO.NET calls, only the order in which they are executed. However, NHibernate does guarantee that the ISession.Find(..) methods will never return stale data; nor will they return the wrong data.

From these few lines should be clear, that NHibernate: ...From time to time the ISession will execute the SQL statements needed to synchronize the ADO.NET connection's state with the state of objects held in memory...

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335