Why can't I just insert the model after I get an error back from the database when trying to insert it the first time:
Report report = null;
using (var session = SessionFactory.OpenSession()) {
try {
using (var transaction = session.BeginTransaction()) {
report = new Report();
session.SaveOrUpdate(report);//Exception: Name field required
transaction.Commit();
}
}
catch { }
try {
using (var transaction = session.BeginTransaction()) {
report.Name = "theName";
session.SaveOrUpdate(report);
//Causes Exception:
//Row was updated or deleted by another transaction (or unsaved-value
//mapping was incorrect): [ReportViewer.DataAccess.Models.Report#22]
transaction.Commit();
}
}
catch { }
}
But when I am updating an existing model, and I get an error, I can make my fixes (in this case set a Name) and just try to update again:
Report report = null;
using (var session = SessionFactory.OpenSession()) {
using (var transaction = session.BeginTransaction()) {
report = new Report();
report.Name = "theName";
session.SaveOrUpdate(report);
transaction.Commit();
}
}
using (var session = SessionFactory.OpenSession()) {
//get entity saved from previous session
report = session.Get<Report>(report.Id);
try {
using (var transaction = session.BeginTransaction()) {
report.Name = null;
session.SaveOrUpdate(report);//Exception: Name field required
transaction.Commit();
}
}
catch { }
try {
using (var transaction = session.BeginTransaction()) {
//updates and does not give an error
report.Name = "theName";
session.SaveOrUpdate(report);
transaction.Commit();
}
}
catch { }
}
As Oskar said, you should discard an NHibernate session after an exception occurs. However, the reason the insert fails is that you have already made the report persistent by calling
SaveOrUpdate
on it (you should useSave
here). When you callSaveOrUpdate
again on the same instance, NHibernate throws an exception because the object is already persistent. Rewriting the code as follows will probably allow the insert to succeed (but it's not recommended):In the update example, calling
SaveOrUpdate
has no effect because the object became persistent when NHibernate loaded it. Understanding NHibernate's instance states and how to work with persistent objects is fundamental and widely misunderstood.A far better approach is to validate your objects before saving them to the database.