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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 called. > > > > > > > > > Now NHibernate does the following: > > > > > > > > 1. The queued insert statement for the new Child is executed > > (let's > > > > > > > > ignore the not null constraint for now). > > > > > > > > 2. Parent version column is updated. > > > > > > > > 3. The child (which shouldn't be in the DB) is commited. The > > next > > > > load > > > > > > > > of the Parent will return the Child which shouldn't be there. > > > > > > > > > I'd really appreciate any advice on this topic - or a > > NHibernate > > > > > > > > bugfix ;-) > > > > > > > > > On 7 Okt., 15:49, John Davidson <[email protected]> wrote: > > > > > > > > > You probably need to do an id check yourself first, before > > the > > > > > > IsDirty. > > > > > > > > > > John Davidson > > > > > > > > > > On Thu, Oct 7, 2010 at 7:32 AM, cremor <[email protected]> > > wrote: > > > > > > > > > > Sadly, a different ID generator is no option for me. My > > > > application > > > > > > is > > > > > > > > > > not the only one accessing the DB and the other systems > > rely on > > > > > > these > > > > > > > > > > sequences. > > > > > > > > > > > What is the reason for getting an ID and flushing the Child > > > > when > > > > > > > > > > checking IsDirty()? Shouldn't it be enough for NHibernate > > that > > > > the > > > > > > ID > > > > > > > > > > of the Child has an unsaved-value? > > > > > > > > > > > On 7 Okt., 12:56, John Davidson <[email protected]> > > wrote: > > > > > > > > > > > The use of sequence is similar to identity in that the db > > > > > > generates > > > > > > > > the > > > > > > > > > > id > > > > > > > > > > > stored rather than the other id generators which create > > the > > > > id > > > > > > within > > > > > > > > > > > NHibernate. For your problem the issue identified in jira > > > > NH-2136 > > > > > > is > > > > > > > > the > > > > > > > > > > > same. > > > > > > > > > > > > The solution is to use an NHibernate created id from > > hi-lo or > > > > > > guid > > > > > > > > based > > > > > > > > > > > generators. > > > > > > > > > > > > John Davidson > > > > > > > > > > > > On Thu, Oct 7, 2010 at 4:09 AM, cremor <[email protected]> > > > > wrote: > > > > > > > > > > > > I currently have the problem that NHibernate creates an > > > > insert > > > > > > > > > > > > statement for new items in a collection of a persistent > > > > entity > > > > > > when > > > > > > > > > > > > calling session.IsDirty(). > > > > > > > > > > > > > My configuration: > > > > > > > > > > > > * NHibernate 3.0.0.Alpha3 > > > > > > > > > > > > * An entity "Parent" with a collection of "Child" > > entities. > > > > > > One-to- > > > > > > > > > > > > many side is mapped as set, inverse, lazy and cascade > > > > > > all-delete- > > > > > > > > > > > > orphan. Many-to-one side is mapped as lazy. > > > > > > > > > > > > * All IDs are using the sequence generator. > > > > > > > > > > > > * Optimistic lock is by version column. > > > > > > > > > > > > * Session.FlushMode is Never. > > > > > > > > > > > > > My use-case: > > > > > > > > > > > > 1. Persistent Parent (already containing some Child > > > > entities) > > > > > > 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 executes a select statement for the ID of > > the > > > > new > > > > > > > > Child > > > > > > > > > > > > and queues an insert statement for the Child using its > > > > current > > > > > > > > > > > > (default) values. (Problem starts here: Why is it > > needed to > > > > get > > > > > > the > > ... > > Erfahren Sie mehr ยป -- 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.
