I have a problem with Session.Clear(), as I understand it this statement should completely reset all changes made in the UOW, the cache etc. The problem is that is does not. My scenario is illustrated in the test below. I add to items, there is a dependency between them I then try to delete the item which the other item is dependent upon. This will cause an exception which is correct. I then clear the session. Finally I try add a new item to the database, when flushing NHibernate will once again try to execute the failing delete statement. Am I misunderstanding the use of Session.Clear()? Or am I missing something else here?
[Fact]
public void Verify_Cant_Clear_Delete()
{
var session = SessionFactory.OpenSession();
var category = new ManufacturerCategory { Name = "category" };
var man = new Manufacturer { Category = category, Name = "man" };
session.Save(category);
session.Save(man);
session.Flush();
try
{
// this will cause
// NHibernate.Exceptions.GenericADOException: could not execute batch command.[SQL: SQL not available]
// ---> System.Data.SqlClient.SqlException: The DELETE statement conflicted with the REFERENCE constraint "ManufacturerCategoryId".
// The conflict occurred in database "LabelMaker-Tests", table "dbo.Manufacturers", column 'Category_id'.
session.Delete(category);
session.Flush();
}
catch (Exception ex)
{
// This should clear the session
session.Clear();
}
try
{
var category2 = new ManufacturerCategory { Name = "category 2" };
session.Save(category2);
session.Flush();
}
catch(Exception ex)
{
// this will cause ONCE AGAIN cause
// NHibernate.Exceptions.GenericADOException: could not execute batch command.[SQL: SQL not available]
// ---> System.Data.SqlClient.SqlException: The DELETE statement conflicted with the REFERENCE constraint "ManufacturerCategoryId".
// The conflict occurred in database "LabelMaker-Tests", table "dbo.Manufacturers", column 'Category_id'.
Assert.True(false);
}
}
You should be using transactions and rollback the transaction on an hibernate exception because…
http://nhibernate.info/doc/nh/en/index.html#manipulatingdata-exceptions
or let the transaction be implicitly rolled back via dispose()…
I’d guess that the Delete() method is one of the inconsistent state methods hinted at in the above quote…