Cascade Save-Update in NHibernate and version column

Cascade save-update in NHibernate mapping means saving parent will automatically save child. So instead of calling Session.SaveOrUpdate(personEmail), calling Session.SaveOrUpdate(person) will cover any email change in email list belongs to same person, given cascade save-update is defined at person model mapping level.

Cascade has a few options to choose from.

The interesting point is, cascade save-update will bump up the version column at both parent and child level.  If Person and Email both have a version column defined in table and entity, cascade saving will change both of them.

This will shock many new NHibernate developers. Their reactions are, what if person has many telephones, many addresses, etc, changing any child will touch version column at person table, this will cause more conflict ions in the real world.

Before answers this question, lets pick another example, like, Order and OrderItem, Order has a total amount which is tightly coupled to all OrderItems in same order. Cascading update OrderItem should bump up version column at Order table, otherwise, things just out of sync. That makes sense.

This complies with aggregate root pattern,as one of the aggregate rules is:

When a change to any object within the Aggregate boundary is committed, all invariants of the whole Aggregate must be satisfied.

For me, it means that the version at root level should reflect changes on any child within the same aggregate.

Now the real question is, are email, telephone and address under the same person’s aggregate? If you are shocked to see the person’s version changed by it’s email/telephone/address modification in your app, just don’t map this relationship as cascade save-update, calling Session.SaveOrUpdate(personEmail) instead of Session.SaveOrUpdate(person).

Before setting cascade save-update, read through aggregate root pattern.

Note, I found a very confusing fact, if parent entity has no version column properties defined, cascade save-update will bypass this behavior, but, if  another child entity with version column is mapped as NotLazyLoad collection under the save root, NHibernate will try to set the version column on that child entity!

Advertisements

My thoughts on Value Object

  • Value object has no identity (or its id has no domain meaning), the equality is decided by their values, (not id), which makes it immutable, changing the value of a value object means (equal) to delete it and add a new one. (This rule apply to value object list as well) Here comes the huge benefit, we can add all validation code right in ctor. Once value object has been successfully created, it must be in valid status. (We have to throw exceptions in ctor?)
  • If we found a “Value object” should be updatable, it’s an entity with a value object component. Watch out, value object can have action methods, like Money.Add(Money), this looks like making the modification on the old one, but it returns a new Money internally.
  • According to the rule, value object can’t exist by itself, must live with its owner. But sometimes we need a maintaince app to admin value objets, like lookup, dictionary stuff (coutry list), I think I have to create avalue object repository, with no update() in it.
    Note: UpdateAll() is doing delete all and add all, who cares the id stuff, we only care values.
    Even value object overrode Equals() method, linq.Distinct() is not calling it! Here is the post giving out the workaround.

         public interface IMyValueObjectRepository<T> where T: MyValueObject<T>
        {
            IEnumerable<string> FetchAll();
            IEnumerable<T> FetchAllForEditing();
            void AddNew(T objToAdd);
            void Delete(T objToDelete);
            void UpdateAll(IEnumerable<T> list);
            T FetchByValue(string value);
        }
    
        [Serializable()]
        public abstract class MyValueObject<T> : IAuditable , IEquatable<T> where T : class
        {
            protected MyValueObject()
            {
                CreatedAt = MyDateTime.Default;
            }
            public virtual DateTime CreatedAt { get; set; }
            public virtual string CreatedBy{ get; set; }
    
            public new abstract int GetHashCode();
            public abstract bool Equals(T other);
    
            public override bool Equals(object obj)
            {
                if (ReferenceEquals(null, obj)) return false;
                if (ReferenceEquals(this, obj)) return true;
                return Equals(obj as T);
            }
    
            // subclass can also implement static operator == and != inside their own class defination
            // see example http://davybrion.com/blog/2009/03/implementing-a-value-object-with-nhibernate/
        }
    
    
  • Value object can be stored into a separated database table with an id column, we can create a protected internal property in it to hide from external users and enable Fluent NHibernate mapping.
  • Most of time value object is embedded in an entity, probably stored in same database table as parent entity, e.g., address, amount. One-to-One.
  • Value Object has different purpose than DTO, but I just found out it’s very convenient to combine those two in one class, so the same validation rule can be shared between server and client in WCF application.
  • We can create a custom list type instead of IList to do the duplication and minim check in ctor.

A interesting question:

I have a lookup list, try to make it value object. Everything works OK until I try to add an “Active” flag on it.

Does this request change it to entity? At least this value object looks like not immutable anymore. Its active flag can be turn on and off, but for me it’s the same object doesn’t matter it’s on or off.

OK, think about turn flag on and off, I think this is same as Money.Add(), (shown in here P. 49 ) turn on/off a value object is no difference than delete the old off/on value object and insert the new one. Good, it’s still immutable.

Evil Validation pattern

We want to use Evil (Entity Validation Library) do DTO validation on UI layer. I then changed Jimmy’s pattern to use the same style as Evil. One big benefit is removing the out keyword in method, Igloo coder said using out is a procedural code smell.

Some principals for validation:

  1. Domain entity should always be valid, even right after new(). ctor has to take all required fields to make a fresh created entity valid.
  2. Never try to valid the entity retrieve database, instead, a data clean up should be done before app released. Or create a cc.net routine to constantly check data on those shared database?
  3. Never try to positionally make a entity invalid, always try valid before making changes, not after then rollback.

       // in Organization
        public void AddEmail(Email emailToAdd)
        {
            // Before add, check duplication
            IEnumerable<string> brokenRules;

            var emailValidator = new EmailValidator(emailToAdd);
            if (!emailValidator.IsValid()) throw new ValidationException(emailValidator.ValidationErrors); 

            var dupValidator = new NoDuplicateEmailAddressValidator(_emails, emailToAdd);
            if (!dupValidator.IsValid()) throw new ValidationException(dupValidator.ValidationErrors); 

            _emails.Add(emailToAdd);
        }

    public class EmailValidator : BaseValidator
    {
        public EmailValidator(Email email)
        {

            if (new SomethingWentWrongSpec.IsSatidsiedBy(entity)
                AddValidationError("Email address has something went wrong. ");

        }

    public class BaseValidator
    {
        private IList<string> _validationErrors = new List<string>();
        public IEnumerable<string> ValidationErrors
        {
            get { return _validationErrors; }
        }

        public bool IsValid()
        {
            return ValidationErrors.Count() == 0;
        }

        protected void AddValidationError(string error)
        {
            _validationErrors.Add(error);
        }    

        protected void AddValidationErrors(IEnumerable<string> errors)
        {
            _validationErrors.Union(errors);
        }
    }
    }

I tried Specification pattern in Domain entities, it’s neat for its nice re-wrote if condition, but the native Specification can’t process error messages, so I just use the validator directly in Domain entity class.

Csla.ObjectFactory III – What’s wrong with UpdateChildren()

Derick Bailey’s post about Csla vs DDD brought out a simple but very interesting question :

Which one is correct?
Person.AddCertificate(), or Person.Certificates.Add()?

Almost the same? But it turns out the 2nd one is NOT “correct”, at least, not in DDD way.

That’s the problem in CSLA. Always thinking in table, data-centric design/dev. An extreme example, FieldManager.UpdateChildren().

How about save? Person.UpdateEmail() or Person.Email.Update(). [Email.Child_Update() in classic CSLA way.]

CSLA is not an ORM tool/framework, but BO carries all the dirty flags, in fact it’s DataPortal doing all the relationship maintenance work. RootBO.Save() is handling all the updates of its children, through FieldManager.UpdateChildren() jumping into each childBO’s internal private Child_XYZ methods. Handy, “clean”, but it’s not “correct”.This is the exactly same problem when I was trying to switch to the new Csla.ObjectFactory way: I had to keep an extra set of Protal methods in child BO, those child portal method,  to work with Parent BO’s FieldManager.UpdateChildren() method.

What if we ignore FieldManager completely? Just let Person.Save() directly call DataPortal.Update<EmailBO>(person.Email) ? Or DataPortal.Update<TelephoneBOCollection>(person.Telephones) ? Then child BO can still use  the general AbstractFactory which only have root level CRUD methods.

The direction Rocky made in ObjectFactory looks right, child CRUD should be done by root BO.  The thing is, it’s not backwards completable. It’s trying to retire FieldManager.UpdateChildren()!

The update route should be RootBO.Save -> Root Factory.Update -> Child Factory.Update, don’t call child BO’s internal Child_XYZ anymore.

Currently for legacy reason I still keep the following code in my ChildBO to bump calls from parent to child’s own factory, those UpdateChildren() in root BO can be alive for awhile, until I move them to root factory, which should be the newly strongly-typed customized UpdateChildren().


private void Child_DeleteSelf(){ DataPortal.Delete(this);}

private void Child_Insert(IParent parent){
     this.ParentId = parent.Id;
     DataPortal.Update(this);
}

private void Child_Update(){
     var newBO = DataPortal.Update(this);
     DataMapper.Map(newBO, this);
}

It might just looks like a wrapper trick, but those DataPortal calls are actually in Factory class now which indeed is in an external true service layer.

In my app, it’s one AbstractFactory for all BOs, both root and child.

I do have a problem now, where should I put transaction scope attribute? It shouldn’t be a big deal, possible solutions:

  1. Create some extra methods in factory not in transaction Scope dedicated for child methods,
  2. Unit of Work pattern?

Look back Ryan’s ProjectTrackerHybrid code, all the child propertis are not registered! Which means they are not in fieldmanager at all. It’s ORM’s job to handle the realationship UpSet (Update/Insert).

About Collection

If I want repository return a group of data, which type should I choose? I saw some NHibernate DAO just return IList<T>, JP’s factory pattern returns IEnumerable, Rocky’s CSLA return costomized collection.

Which one is better? After I read this post about collection, I feel the power of the DDD, this post described a typical filter problem:

public class BookCatalog {
List<Book> findBooksByAuthor( … ) {..}
List<Book> findBooksByPublisher( … ) {..}
List<Book> findBooksByAuthorAndPublisher( … ) {..}

Can be easily solve by changing method return type from List<> to costomized collection:

public class BookCatalog {
BookCatalog findByAuthor( … ) {..}
BookCatalog findByPublisher( … ) {..}
BookCatalog findByPublishDates( DateTime,DateTime ) {..}
BookCatalog findByPublishingCountry( … ) {..}

The method chain is here:

BookCatalog.findByAuthor(“Frank”).findByPublisher(“Frank Inc.”)…

The new LinQ where syntax has the similar effect.

I still don’t know why IEnumeralbe should be used, seems it’s usefule when passing data to UI / controls, but why it’s also popular in passing data from DAL to upper layers.

Validation in Domain Layer

Following JP’s demo code, I made some changes trying to make code more understandable.

  1. Move Rules/RuleSet sub class out from entity class. Make it a seperate class, say MyEntityRules.
  2. Re-write validate() in entity class instead of DomainObject ancestor, because my entity classes are from LinqToSql, it’s hard to intercept entity’s constructor. In this override validate(), I put code like this:

    return MyEntityRules.Default.BrokenBy(this);

  3. Remove unused ruleset field from DomainObject, make validate() in DomainObject throw throw new NotImplementedException();

It works well in my app. It looks like I can easily create more validate method in different situation. e.g, MyEntityRules.High, MyEntityRules.Low, etc…