I have two classes with parent/child relation: Parent and Child.
In my test code an Exception is thrown (see log file).
What's the reason for the exception?
log file:
Code:
13:02:30.468 [4036] DEBUG NHibernate.Transaction.AdoTransaction - begin
13:02:30.468 [4036] DEBUG NHibernate.Connection.DriverConnectionProvider - Obtaining IDbConnection from Driver
13:02:30.468 [4036] DEBUG NHibernate.Impl.SessionImpl - deleting a transient instance
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - deleting [test.Parent#8]
13:02:30.484 [4036] DEBUG NHibernate.Engine.Cascades - processing cascades for: test.Parent
13:02:30.484 [4036] DEBUG NHibernate.Engine.Cascades - cascading to collection: test.Parent.Children
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - deleting a transient instance
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - deleting [test.Child#10]
13:02:30.484 [4036] DEBUG NHibernate.Engine.Cascades - done processing cascades for: test.Parent
13:02:30.484 [4036] DEBUG NHibernate.Engine.Cascades - processing cascades for: test.Parent
13:02:30.484 [4036] DEBUG NHibernate.Engine.Cascades - done processing cascades for: test.Parent
13:02:30.484 [4036] DEBUG NHibernate.Transaction.AdoTransaction - commit
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - flushing session
13:02:30.484 [4036] DEBUG NHibernate.Impl.CollectionEntry - Collection dirty: [test.Parent.Children#8]
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - Flushing entities and processing referenced collections
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - Processing unreferenced collections
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - collection dereferenced: [test.Parent.Children#8]
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - scheduling collection removes/(re)creates/updates
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - Flushed: 0 insertions, 0 updates, 2 deletions to 2 objects
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - Flushed: 0 (re)creations, 0 updates, 1 removals to 1 collections
13:02:30.484 [4036] DEBUG NHibernate.Impl.Printer - listing entities:
13:02:30.484 [4036] DEBUG NHibernate.Impl.Printer - test.Parent{Id=8, Children=[]}
13:02:30.484 [4036] DEBUG NHibernate.Impl.Printer - test.Child{Id=10, Parent=Parent#8}
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - executing flush
13:02:30.484 [4036] DEBUG NHibernate.Persister.EntityPersister - Deleting entity: [test.Child#10]
13:02:30.484 [4036] DEBUG NHibernate.Impl.BatcherImpl - Opened new IDbCommand, open IDbCommands :1
13:02:30.484 [4036] DEBUG NHibernate.Impl.BatcherImpl - Building an IDbCommand object for the SqlString: DELETE FROM Child WHERE id = :id
13:02:30.484 [4036] DEBUG NHibernate.Type.NullableType - binding '10' to parameter: 0
13:02:30.484 [4036] DEBUG NHibernate.Impl.BatcherImpl - Closed IDbCommand, open IDbCommands :0
13:02:30.484 [4036] ERROR NHibernate.Impl.SessionImpl - could not synchronize database state with session
NHibernate.HibernateException: SQL insert, update or delete failed (expected affected row count: 1, actual affected row count: 0). Possible causes: the row was modified or deleted by another user, or a trigger is reporting misleading row count.
at NHibernate.Impl.NonBatchingBatcher.AddToBatch(Int32 expectedRowCount)
at NHibernate.Persister.EntityPersister.Delete(Object id, Object version, Object obj, ISessionImplementor session)
at NHibernate.Impl.ScheduledDeletion.Execute()
at NHibernate.Impl.SessionImpl.Execute(IExecutable executable)
at NHibernate.Impl.SessionImpl.ExecuteAll(IList list)
at NHibernate.Impl.SessionImpl.Execute()
13:02:30.484 [4036] DEBUG NHibernate.Impl.SessionImpl - transaction completion
hbm file:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="test.Parent, test" table="Parent">
<id name="Id" column="id" type="Int32" unsaved-value="-1">
<generator class="identity" />
</id>
<set name="Children" lazy="false" cascade="all-delete-orphan" inverse="true">
<key column="parent_id"/>
<one-to-many class="test.Child, test"/>
</set>
</class>
<class name="test.Child, test" table="Child">
<id name="Id" column="id" type="Int32" unsaved-value="-1">
<generator class="identity" />
</id>
<many-to-one name="Parent" class="test.Parent, test" column="parent_id" not-null="true"/>
</class>
</hibernate-mapping>
classes:
Code:
public class Parent
{
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
protected Iesi.Collections.ISet children;
public Iesi.Collections.ISet Children
{
get
{
if (children == null) children = new Iesi.Collections.ListSet();
return children;
}
set { children = value; }
}
public Parent() {
id = -1;
}
}
Code:
public class Child
{
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
protected Parent parent;
public Parent Parent
{
get { return parent; }
set { parent = value; }
}
public Child() {
id = -1;
}
}
Test code:
Code:
Configuration configuration = new Configuration();
configuration.AddAssembly( "test" );
ISessionFactory factory = configuration.BuildSessionFactory();
ISession session;
ITransaction tx;
// create a parent with one child
Parent parent = new Parent();
Child child = new Child();
parent.Children.Add( child );
child.Parent = parent;
session = factory.OpenSession();
tx = session.BeginTransaction();
parent = (Parent) session.SaveOrUpdateCopy( parent );
tx.Commit();
session.Close();
// remove child from parent
parent.Children.Remove( child );
session = factory.OpenSession();
tx = session.BeginTransaction();
Parent savedParent = (Parent) session.SaveOrUpdateCopy( parent );
tx.Commit();
session.Close();
session = factory.OpenSession();
tx = session.BeginTransaction();
// problem
session.Delete( parent );
tx.Commit();
session.Close();