I concur with "cremor" that this is clearly a bug regardless of what
identity method or presentation layer design are used because the
behavior of IsDirty does not match its description. The description of
IsDirty indicates this:

"Does this ISession contain any changes which must be synchronized
with the database? Would any SQL be executed if we flushed this
session?"

So, by calling IsDirty I would expect to know if any SQL statements
will be executed if I call Save, Flush, etc... There should be no SQL
statements executed as part of this property call. Period.
I would really like NH team to fix this bug or at least change the
description of this property so people don't waste hours of their
precious time troubleshooting this issue.

In my case I have very bazaar behavior as result of this bug. I have a
persisted parent that has new child item (1) with the "identity" ID,
which in turn has new child (2) in the "bag" collection. When I call
IsDirty, the child 1 is inserted, but the child 2 is not. According to
the description of IsDirty I expect that nothing will be inserted
until I call Save or Flush.

On Nov 3, 1:18 am, John Davidson <jwdavid...@gmail.com> wrote:
> That is a problem with the design of the model.If something needs to change
> as a result of an action in the UI _and_ visible at the time of the change
> then it needs to be managed in the controller rather than in the domain. You
> may need to verify that the DTO passed to the domain is valid at the domain
> level.
>
> John Davidson
>
>
>
> On Wed, Nov 3, 2010 at 2:34 AM, cremor <cre...@gmx.net> wrote:
> > So you say my domain objects should only be changed when the user
> > clicks OK. But how would I then handle calculated properties? E.g.,
> > the user changes proptery A in the UI and expects some other (read-
> > only) property B to change as well. But the code to calculate property
> > B is of course in the domain model.
>
> > On 29 Okt., 15:28, John Davidson <jwdavid...@gmail.com> wrote:
> > > So the problem is in the WPF binding where it creates the Domain Object
> > > before it is actually desired, or in the WPF binding that does not clear
> > the
> > > Domain Object properly when the user decides to not really save. It still
> > > comes down to how a DTO should talk to a Domain Object - only after the
> > user
> > > interface is fully completed for the unit of work.
>
> > > John Davidson
>
> > > On Fri, Oct 29, 2010 at 10:15 AM, cremor <cre...@gmx.net> wrote:
> > > > That's exaclty what I'm doing. Neither the domain objects nor the
> > > > session know anything about the ViewModel. Session.IsDirty just checks
> > > > the domain model, because that are the entities that are assigned to
> > > > the session.
>
> > > > 1. User adds a row in a grid.
> > > > 2. Parent ViewModel object creates a new Child domain object and Child
> > > > ViewModel object (ViewModel object has a reference to domain object,
> > > > but not the other way round).
> > > > 3. Parent ViewModel adds the new Child ViewModel to a
> > > > ViewModelCollection (ParentVM.ChildVMs).
> > > > 4. ViewModelCollection gets the Child domain object out of the Child
> > > > ViewModel object and inserts it to the domain collection
> > > > (Parent.Children).
> > > > 5. Session.IsDirty() is called, sees the new Child entity in the
> > > > collection (Parent.Children) and queues an insert statement.
>
> > > > On 29 Okt., 15:29, John Davidson <jwdavid...@gmail.com> wrote:
> > > > > In this case then you should be doing the IsDirty check on the Domain
> > > > Model
> > > > > objects after the updates from the ViewModel in the business layer.
> > The
> > > > > IsDirty check should not reference the ViewModel objects for this
> > > > purpose.
>
> > > > > John Davidson
>
> > > > > On Fri, Oct 29, 2010 at 8:07 AM, cremor <cre...@gmx.net> wrote:
> > > > > > Aaaaah, big missunderstanding here! I don't have a web project, I
> > have
> > > > > > a WPF rich client.
> > > > > > I'm using the Session-per-screen concept (with my own UnitOfWork
> > > > > > implementation which handles the session), so:
>
> > > > > > 1. Screen is opened.
> > > > > > 2. New NHibernate session is opened (FlushMode = Never).
> > > > > > 3. Data is loaded to domain objects.
> > > > > > 4. Data is passed to ViewModel objects.
> > > > > > 5. User modifies ViewModel objects (through WPF data binding).
> > > > > > 6. ViewModel objects check if the data is valid and if yes, modify
> > the
> > > > > > domain objects.
> > > > > > 7. Screen wants to know if it should enable the save button, which
> > > > > > results in a session.IsDirty() call (after some layers of
> > > > > > abstraction).
> > > > > > 8. User clicks save, which results in a session.Flush() call.
> > > > > > 9. Session is closed.
>
> > > > > > On 29 Okt., 13:07, John Davidson <jwdavid...@gmail.com> wrote:
> > > > > > > I did not say that IsDirty should not be used for Domain objects.
> > I
> > > > did
> > > > > > say
> > > > > > > it should not be used for ViewModel objects.
>
> > > > > > > The proper sequence of events should demonstrate why IsDirty
> > checking
> > > > > > should
> > > > > > > not be attempted with ViewModel objects.
>
> > > > > > > 1. Start a Web Page request
> > > > > > > 2. Open a new NHibernate session
> > > > > > > 3. Get Domain objects from DB (using NHibernate)
> > > > > > > 4. Create ViewModel objects from Domain data (if NHibernate then
> > > > hydrate
> > > > > > via
> > > > > > > projections)
> > > > > > > 5. End NHibernate Session
> > > > > > > 6. Display Web page
> > > > > > > 7. Users interacts with Web Page and Starts New Web Request
> > > > > > > 8. Open a new NHibernate Session (this session knows nothing
> > about
> > > > prior
> > > > > > > session)
> > > > > > > 9. Get Domain objects from DB (using NHibernate)
> > > > > > > 10. Move ViewModel data to Domain objects (using business layer)
> > > > > > > 11. Persist Domain model changes to DB (using NHibernate)
> > > > > > > 12. Update ViewModel with business information
> > > > > > > 13. End NHibernate Session
> > > > > > > 14. Display Web Page to User.
>
> > > > > > > The ViewModel objects are not part of what NHibernate is
> > managing, so
> > > > it
> > > > > > > makes no sense to try to have ISDirty checks from NHibernate on
> > them.
> > > > > > > IsDirty checks can be performed on the Domain Model objects and
> > then
> > > > > > handled
> > > > > > > in the the business layer.
>
> > > > > > > If you are trying to have the ViewModel objects managed by
> > NHibernate
> > > > are
> > > > > > > you trying to keep a Session open between Web Requests?
>
> > > > > > > John Davidson
>
> > > > > > > On Fri, Oct 29, 2010 at 1:29 AM, cremor <cre...@gmx.net> wrote:
> > > > > > > > Neither is my View Model identical to my Domain Model, nor is
> > the
> > > > > > > > Domain Model simple.
>
> > > > > > > > So, if I understand your advices correctly, you are basically
> > > > saying
> > > > > > > > that IsDirty shouldn't be used to check if there are any
> > changes in
> > > > > > > > the domain entities, rather I should implement my own change
> > > > tracking?
> > > > > > > > Then I'll have to ask, what is the purpose of IsDirty?
>
> > > > > > > > On 29 Okt., 00:17, John Davidson <jwdavid...@gmail.com> wrote:
> > > > > > > > > NHibernate is meant to manage the Object-Relational interface
> > > > between
> > > > > > > > your
> > > > > > > > > Domain Model and your persistence layer (RDBMS).
>
> > > > > > > > > It is not used to manage the ViewModel interface with the
> > Domain
> > > > > > Model.
> > > > > > > > Any
> > > > > > > > > functionality that seems to support this interface is
> > incidental
> > > > and
> > > > > > as
> > > > > > > > you
> > > > > > > > > are finding will not work the way you are hoping. There are
> > > > samples
> > > > > > where
> > > > > > > > > the ViewModel and the Domain Model are identical, and I wish
> > > > these
> > > > > > > > samples
> > > > > > > > > had never been created, because they only work correctly
> > because
> > > > of
> > > > > > the
> > > > > > > > > simplicity of the Domain Model, and everything falls apart
> > when a
> > > > > > more
> > > > > > > > > complex Domain Model and ViewModel are attempted.
>
> > > > > > > > > I would seriously recommend you rethink your architecture.
> > > > NHibernate
> > > > > > is
> > > > > > > > not
> > > > > > > > > a panacea for poor design.
>
> > > > > > > > > John Davidson
>
> > > > > > > > > On Thu, Oct 28, 2010 at 11:43 AM, cremor <cre...@gmx.net>
> > wrote:
> > > > > > > > > > I am using ViewModel objects for the binding to my screens.
> > But
> > > > my
> > > > > > > > > > ViewModel objects must write the data to the domain
> > > > (NHibernate)
> > > > > > > > > > objects, how would I use the business logic otherwise?
> > > > > > > > > > Also, if I only write the data to the domain objects on
> > save,
> > > > I'd
> > > > > > have
> > > > > > > > > > to implement change tracking myself. NHibernate already
> > > > implements
> > > > > > > > > > change tracking, so why not use it?
>
> > > > > > > > > > On 28 Okt., 17:28, John Davidson <jwdavid...@gmail.com>
> > wrote:
> > > > > > > > > > > This is the reason for using a DTO rather than the
> > NHibernate
> > > > > > object.
> > > > > > > > The
> > > > > > > > > > > DTO data is only moved to the NHibernate object after the
> > > > user
> > > > > > has
> > > > > > > > > > pressed
> > > > > > > > > > > save. Screen objects should not be NHibernate objects.
>
> > > > > > > > > > > John Davidson
>
> > > > > > > > > > > On Thu, Oct 28, 2010 at 9:31 AM, cremor <cre...@gmx.net>
> > > > wrote:
> > > > > > > > > > > > Just for curiosity I switched my ID generator from
> > Sequence
> > > > to
> > > > > > > > > > > > SeqHiLo. Calling session.IsDirty() now doesn't execute
> > a
> > > > select
> > > > > > > > > > > > statement for the ID anymore (which is expected with
> > > > SeqHiLo),
> > > > > > but
> > > > > > > > it
> > > > > > > > > > > > still queues the insert statement.
> > > > > > > > > > > > Then I even implemented my own IIdentifierGenerator
> > which
> > > > just
> > > > > > > > returns
> > > > > > > > > > > > an increasing number in Generate(), and IsDirty() STILL
> > > > queues
> > > > > > the
> > > > > > > > > > > > wrong insert statement!
>
> > > > > > > > > > > > What's the reason for this?
>
> > > > > > > > > > > > I highly doubt that this behaviour is as designed.
> > Because,
> > > > in
> > > > > > > > > > > > addition to the problem with not null or check
> > constraints
> > > > and
> > > > > > the
> > > > > > > > > > > > inconsistent behaviour I explained in my first post,
> > this
> > > > even
> > > > > > > > results
> > > > > > > > > > > > in the following behaviour, that is clearly a bug in
> > > > NHibernate
> > > > > > in
> > > > > > > > my
> > > > > > > > > > > > opinion (please tell me if I'm wrong):
>
> > > > > > > > > > > > Use-case:
> > > > > > > > > > > > 1. Persistent Parent is loaded.
> > > > > > > > > > > > 2. A new Child is added to the collection.
> > > > > > > > > > > > 3. session.IsDirty() is called (UI checks, if it should
> > > > enable
> > > > > > the
> > > > > > > > > > > > save button).
> > > > > > > > > > > > 4. NHibernate queues an insert statement for the Child
> > > > using
> > > > > > its
> > > > > > > > > > > > current (default) values.
> > > > > > > > > > > > 5. User deletes the just created Child again (it is
> > removed
> > > > > > from
> > > > > > > > the
> > > > > > > > > > > > collection in the Parent).
> > > > > > > > > > > > 6. User saves the changes, session.Flush() is
>
> ...
>
> read more »- Hide quoted text -
>
> - Show quoted text -

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to nhus...@googlegroups.com.
To unsubscribe from this group, send email to 
nhusers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to