It looks like Rollback() does not roll back changes when the call is followed by session.CreateCriteria() on the same table.
In this code sample, I save the User row into the Users table, but before I call commit(), I forced an exception to cause the row to be rolled back.
However, if the Rollback() call is followed with session.CreateCriteria(typeof(Users)).List(), the row gets written to the database anyway.
However, if I disconnect the session (without a CreateCriteria(...)), the sample code works as expected. I think this is a bug. Thanks.
This is the code sample:
Code:
public void Test1()
{
Configuration cfg = new Configuration();
IDictionary props = new Hashtable();
props["hibernate.connection.provider"] = "NHibernate.Connection.DriverConnectionProvider";
props["hibernate.dialect" ] = "NHibernate.Dialect.FirebirdDialect";
props["hibernate.connection.driver_class" ] = "NHibernate.Driver.FirebirdDriver" ;
props["hibernate.connection.connection_string"] = "User=SYSDBA;Password=xxx;Database=TestDB.gdb;DataSource=localhost;Port=3050;Dialect=3;Charset=NONE;Role=;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=2048;ServerType=0" ;
foreach( DictionaryEntry de in props )
{
cfg.SetProperty( de.Key.ToString(), de.Value.ToString() );
}
cfg.AddAssembly("Test");
ISessionFactory factory = cfg.BuildSessionFactory();
ISession session = factory.OpenSession();
try
{
ITransaction transaction = session.BeginTransaction();
try
{
if(!session.IsConnected)
{
session.Reconnect();
}
// Roles newRole = new Roles();
// newRole.RoleName = "Guest";
// session.Save(newRole);
IList roles = session.Find("from Roles as roles where RoleName = "+"'Guest'");
Users newUser = new Users();
newUser.UserId = "joe";
newUser.Password = "123";
newUser.Role = (Roles) roles[0];
// Tell NHibernate that this object should be saved
session.Save(newUser);
// Force an exception to test rollback bug
throw new Exception("Force it");
// commit all of the changes to the DB and close the ISession
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
}
/*
** If the next four lines are commented out, Rollback works and user row is not saved
** But if the next four lines is executed after rollback, an row "joe" will be written to the database
IList userList = session.CreateCriteria(typeof(Users)).List();
foreach(Users user in userList)
{
string id = user.UserId;
}
*/
}
catch (Exception)
{
// do nothing
}
finally
{
session.Disconnect();
session.Close();
}
}