I've setup nhibernate but I have problems with validating entity before the actual save and commit to database. As I load and change persistent entity, validation that goes after is accessing the database and by doing so commiting the transaction, thus saving entity in database before the actual validation result is known.
I use Repository pattern in .NET MVC web app and it goes like this:
public ActionResult Edit(int id, Entity entity)
{
var repository = new EntityRepository();
// get persistent entity from nhibernate
var entityOriginal = repository.GetById(id);
// copy data from input entity to persistent entity
entity.CopyDataToEntity(entityOriginal);
// if validation ok save to database
// this validations is problematic becouse it needs info from database and uses transaction
ValidationResult validationResult = entityOriginal.Validate();
if (validationResult.IsValid())
{
repository.Save(entityOriginal);
// everything ok, redirect to view entity page
return RedirectToAction("view");
}
else
{
repository.Evict(prateciList);
foreach (var message in validationResult.ErrorMessages)
{
ModelState.AddModelError(message.Key, message.Value);
}
return RedirectToAction("pogledaj");
}
}
UPDATE: clarification ok here's the code:
// get persistent entity from nhibernate
var entityOriginal = repository.GetById(id);
entity.CopyDataToEntity(entityOriginal);
ValidationResult validationResult = entityOriginal.Validate();
- I get the persistent entity from the database
- I change it... now if session is flushed it will be persisted in database
- I do entity.Validate() which gets another entity from database and commits in process (as you have to commit even for fetching from database)!... so entity I try to validate is persisted in database during the validation itself.
So the problem is that Entity.Validate() check the database for correctly inputed data, and since transaction is commited even on session.Get(), changed entity is saved (valid or invalid) right there.
My repository implementation is classic:
public virtual bool Save(T entity)
{
var session = SessionProvider.GetRequestSession(this.DatabaseName);
using (var transaction = session.BeginTransaction())
{
try
{
session.SaveOrUpdate(entity);
transaction.Commit();
}
catch (Exception ex)
{
_log.Error("Could not save object to database.", ex);
if (transaction.IsActive)
{
transaction.Rollback();
}
session.Close();
return false;
}
}
return true;
}
How can I achieve validation that can check stuff in database?
Possible solution be to validate before I make any changes to persistent object, but this is such a pain to do there must be a better way. Thank you for your help.
The solution I've found is very ugly but it works:
Still looking for a better solution though.