Fabio, thank you for the links. I appreciate you taking some of your valuable time to consider my issues. I've read them and I think they would have been very useful in the initial design stage of my application, but at this juncture altering the application infrastructure to line up with the recommended structures there would be a massive undertaking which I hope is not necessary. I feel like I should explain more fully how I'm doing things in my application to add this this conversation because it doesn't seem like anyone else uses patterns similar to what we've ended up with. I apologize in advance for the length of this post. Hopefully people will find it interesting.
I've got three projects- .Core, .Data, and .UI .Core is exactly what you would expect it to be- nothing but the domain model and business logic. I don't think I need to elaborate in detail on how this is set up. It has no dependencies. .UI is just the code required to present the user interface. No business logic exists here. I'm attempting to minimize the NHibernate specific code in here as well. It is dependant on .Core and .Data. .Data's design is what is somewhat unique. It has 4 major areas of code. -It contains the hbm.xml mappings for the .core objects that have persistence. -It contains a definition for two kinds of Sessions which can be thought to represent a unit of work- ReadSession and WriteSession. These inherit from DBSession which is just an IDisposable wrapper for the ISession. WriteSession is used by forms that can edit data, ReadSession is for read-only forms. WriteSession contains methods to Delete and Save. All sessions contain methods to evict and re-attach POCOs, and one question I have is if I'm using the appropriate NHibernate methods to do this. Whenever HibernateExceptions are experienced, the Session will rollback the transaction as recommended by the documentation. -It contains a Generic Database<T> class which can be used to query any persisted table for single objects. Each query in here, for example, GetByID, takes a DBSession in addition to whatever other parameters are required. -Finally it contains a collection of Query classes which perform more advanced or optimized queries for specific domain objects or maps of objects. These also take a DBSession and perform the query using the ISession that is wrapped in the DBSession. So your standard editing form will open, declare a WriteSession, then either use the generic database class or a query class to grab the objects it's interested in. For the life of the form, the DBSession remains open, and the DBSession maintains an open transaction with ReadUncommited isolation level. The user edits the object data via the form, then either clicks a save button (which commits changes, then disposes the active transaction and starts a new transaction) or goes to close the form. When closing the form asks the DBSession if it is dirty. If it is, it asks the user if they want to commit or discard their changes. So here are my /big/ questions. 1- Which NHibernate session methods should I be using to attach/ reattach POCO objects to a session? I'm using ISession.Update, because these objects could change between sessions. I see Lock- but the documentation of how this works in its various modes is somewhat confusing. I'm game for moving to a different transaction model, but I'll (obviously) need a better understanding of this functionality in order to successfully implement it 2- Is this transaction model appropriate? I see a lot of advocacy for keeping transactions open only as long as there is data being queried or updated. One aspect of my transaction model that I do appreciate is that it allows me to be sloppy with pre-loading data, and when the user's action requires an object wrapped in a proxy, the transaction is always up and ready to handle the proxy without me needing to keep track of which objects would be proxies and which would be domain objects based on the initial query. I'm OK with changing this design, I just need to know that what I'm doing is something that is not supposed to be supported- or to be more specific, that NHibernate does not contain the functionality that would be required to support this transaction model without unintended consequences- such as the full map save I'm seeing now. 3- I see a lot of discussion about the repository design for NHibernate applications, and I've attempted to emulate the best parts of this between the class specific queries and the generic Database<T> class. However, am I missing the best part of this by not fully integrating the transaction management in a strongly typed repository class? Thank you for your time. On Jan 26, 9:34 am, Fabio Maulo <[email protected]> wrote: > Have a look to the ChinoOk series on this > bloghttp://jfromaniello.blogspot.com/2009/08/introducing-nhiberate-and-wp... > > <http://jfromaniello.blogspot.com/2009/08/introducing-nhiberate-and-wp...>It > is based on CpBT (the series end > here)http://fabiomaulo.blogspot.com/2009/01/aspect-conversation-per.html > > <http://fabiomaulo.blogspot.com/2009/01/aspect-conversation-per.html>If you > prefer something more easy to > followhttp://fabiomaulo.blogspot.com/2009/09/nhibernate-in-winform-coupled.... > > 2010/1/26 Dietrich <[email protected]> > > > > > > > Windows forms. > > > On Jan 25, 10:51 pm, Fabio Maulo <[email protected]> wrote: > > > Web or Win ? > > > > 2010/1/25 Dietrich <[email protected]> > > > > > I am attempting to generate a new usage pattern to avoid this problem > > > > where a session is not kept open for longer than a single procedure > > > > that requires data access. The save button works just fine, but now my > > > > dirty checking on form close has become a problem. > > > > On close, I create a new session, call .SaveOrUpdate with the primary > > > > object, and then check if it's dirty. It always is, even when the > > > > object has not changed from the database. I also tried .Lock(obj, > > > > ReadMode.Upgrade), and this always returns that it's not dirty, even > > > > when the object HAS changed from the database. > > > > > There are many methods that all seem designed to handle these kinds of > > > > circumstances. Which ones should I be using? > > > > > On Jan 24, 12:23 pm, Dietrich <[email protected]> wrote: > > > > > I've got a winforms production application that putting locks on > > three > > > > > tables in my SQL 2005 server almost all day long. I have many forms > > in > > > > > the system which use the same pattern, so what confuses me is that > > > > > only one specific form seems to be causing these locks. > > > > > > When the form is opened, it creates a session and loads the objects > > > > > that could be edited on that form. It keeps that session open for the > > > > > lifetime of the form and I use the session to perform a dirty check > > > > > when the form is closed to ask if the user wants to commit their > > > > > changes. > > > > > > The sessions are opened with a readuncommited isolation level. > > > > > > So question 1 - is this the right way to handle sessions? Should I > > use > > > > > one session to load the data for the form and another session to > > > > > commit the changes when they close a form? If so, how should I handle > > > > > dirty tracking? > > > > > > Question 2 - what specific kind of activity inside a session would > > > > > create table locks? Like I said, I use this same pattern on many > > > > > forms, but only one form seems to show this behavior. I'll be happy > > to > > > > > provide code, but this form hits a ton of code within my various > > > > > layers, and in the interest of brevity, I don't want to post a ton of > > > > > code that couldn't possibly have this impact. > > > > > > Thank you! > > > > > -- > > > > You received this message because you are subscribed to the Google > > Groups > > > > "nhusers" group. > > > > To post to this group, send email to [email protected]. > > > > To unsubscribe from this group, send email to > > > > [email protected]<nhusers%[email protected] > > > > > > > <nhusers%[email protected]<nhusers%252bunsubscr...@googlegroup > > s.com> > > > > > . > > > > For more options, visit this group at > > > >http://groups.google.com/group/nhusers?hl=en. > > > > -- > > > Fabio Maulo > > > -- > > You received this message because you are subscribed to the Google Groups > > "nhusers" group. > > To post to this group, send email to [email protected]. > > To unsubscribe from this group, send email to > > [email protected]<nhusers%[email protected] > > > > > . > > For more options, visit this group at > >http://groups.google.com/group/nhusers?hl=en. > > -- > Fabio Maulo -- You received this message because you are subscribed to the Google Groups "nhusers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.
