I have an account model object and a UNIQUE constraint for the account name. In Domain Driven Design using nHibernate, how should I check the unicity name before inserting or updating an object?
I do not want to rely on the nHibernate exception to catch the error. I would like to return a more beautiful error message to my user than the obscure could not execute batch command.[SQL: SQL not available]
In the question Where should I put a unique check in DDD? , someone suggested using such a specification.
Account accountA = _accountRepository.Get(123); Account accountB = _accountRepository.Get(456); accountA.Name = accountB.Name; ISpecification<Account> spec = new Domain.Specifications.UniqueNameSpecification(_accountRepository); if (spec.IsSatisfiedBy(accountObjA) == false) { throw new Domain.UnicityException("A duplicate Account name was found"); }
with specification code like:
public bool IsSatisfiedBy(Account obj) { Account other = _accountRepository.GetAccountByName(obj.Name); return (other == null); }
This works for inserts, but not when performing an update, because. I tried changing the code to:
public bool IsSatisfiedBy(Account obj) { Account other = _accountRepository.GetAccountByName(obj.Name); if (obj == null) { // nothing in DB return true; } else { // must be the same object. return other.Equals(obj); } }
The problem is that nHibernate issues an update for the database when it executes GetAccountByName() to restore a possible duplicate ...
return session.QueryOver<Account>().Where(x => x.Name == accntName).SingleOrDefault();
So what should I do? Is the specification in the wrong way?
Thanks for your thoughts!
nhibernate domain-driven-design
dstj
source share