39828

How can this be done with (N)Hibernate?

I'm creating a windows forms application with NHibernate. It's an MDI application, so there is no limit to how many forms the user can have open at the same time (probably many).

For most forms I want to have an "OK" and a "Cancel" button. Both close the form, but "OK" also saves the modified data to the DB. The forms can be pretty complex, and the modifications are likely to touch a whole graph of objects, adding some, deleting some, and changing some more. It would be good if the changes could be automatically detected and persisted as needed, without the need to manually keep track of each of them.

What would be a good way to do this?

<strong>Extra information</strong>: I can make whatever DB schema I want. I'm using MSSQL 2008 and currently have decided for GUID primary keys (with guid.comb generator) and a TIMESTAMP column for optimistic concurrency.

I tried to simply set FlushMode of a NHibernate ISession to Never, doing all modifications as needed, and then calling Flush() if the user clicked OK. But that didn't work.

Answer1:

A few possible solutions, assuming that you're using one ISession per form instance:

<ol> <li>Call ISession.Clear if the user cancels.</li> <li>Set the FlushMode to Commit and only initiate a transaction when the user clicks OK.</li> <li>Stick with your original approach of using Manual FlushMode. It should work and the behavior you're seeing is not a bug.</li> </ol>

Since you're using GUIDs for primary keys, you should not run into the issue of NH unexpectedly flushing a session because it needs the database to generate an identifier. You still need to be aware of scenarios where NH may flush before a select to ensure consistent results.

I don't think you need to worry about opening and closing the database connection. My understanding is that NH is very good about managing that.

Answer2:

This should help: NHibernate Best Practices with ASP.NET, 1.2nd Ed. (I know it's ASP.NET, but you should find the information useful and easily transferable to WinForms.)

In short, one should opt for a sesson per window architecture. Making impossible to open two different windows for the same exact task makes sense here. Then, you perhaps want to create an instance of the NHibernate ISession API on Form_Load(). At the end, if the user clicks OK, then just BeginTransaction(), Flush() the session, and Commit() the transaction, otherwise rolls it back.

Answer3:

Maybe if you wrap the whole thing in a transaction and commit the transaction when the user clicks OK?

Recommend

  • Function to print all permutations of all subsets of the array [closed]
  • sas drop value through the whole data
  • Jquery assign value to JSP variable
  • Melt the data frame with 4 columns to three columns
  • Best practice to keep RSS feeds unique in sql database
  • Access bindingsource column value
  • Issues after I add a command filter to textview
  • Scons: create late targets
  • Random(staticSeed).Next() alternative that will never change implementation and is guaranteed consis
  • GUIDs in DLLs (.Net)
  • Set up the Android-Facebook sdk for Netbeans
  • Is there a greater chance to collide when comparing GUIDs based on a hash vs \"Guid.NewGuid()?
  • ASP Net Core - Mixing External Identity Provider with Individual User Accounts for Audit Tracking
  • Is this hack a defined behavior for T4
  • Calling right overload of the java method from jython
  • Passing and ArrayList through intent
  • Change color of row programmatically in WatchKit
  • css font-size and line-height not matching the baseline
  • Stitching 2 images (OpenCV)
  • how to set to NULL all the filestream varbinary(max) fields?
  • What is this strange character in chrome's resource css viewer?
  • AlertDialog style when using setView()
  • encoding issues with content in response from HttpWebRequest
  • Possible to get mouse events fired when cursor is outside page?
  • How do I display a dialog that asks the user multi-choice questıon using tkInter?
  • how does System.Web.HttpRequest::PathInfo work?
  • Array with custom indexes in Ionic2
  • Eloquent update method change created_at timestamp
  • Test if a set exists before trying to drop it
  • Why querying a date BC is changed to AD in Java?
  • Chrome doesn't support silverlight anymore? How to solve this?
  • Database structure design with variable amounts of fields
  • Illegal mix of collations for operation for date/time comparison
  • Check if a string to interpolate provides expected placeholders
  • Javascript + PHP Encryption with pidCrypt
  • Calling of Constructors in a Java
  • VB.net deserialize, JSON Conversion from type 'Dictionary(Of String,Object)' to type '
  • using conditional logic : check if record exists; if it does, update it, if not, create it
  • Recursive/Hierarchical Query Using Postgres
  • How can I use threading to 'tick' a timer to be accessed by other threads?