开发者

NHibernate StaleStateException on Delete of child object

Is it possible to say something of the origin of this exception from the StackTrace?

StaleStateException:  Unexpected row count: 0; expected: 1

I'm displaying parent/child object collections in multiple DataGridViews, and perform varioius add/delete/save commands. This exception occur when attempting to delete a child row/entity. I use DefaultCascadeAll convention.

After this exception, the respective parent entity has been deleted from the database, even though that was not called for. So in the image shown, next 开发者_如何学编程time I start the program; Store Id=55 is non existing.

Program window: http://img822.imageshack.us/img822/4686/ss20110201212511.png

StackTrace: http://img145.imageshack.us/img145/408/ss20110201211702.png

Mappings:

public class StoreMap : ClassMap<Store>
{
    public StoreMap()
    {
        Id(x => x.Id);
        Map(x =>  x.Name);
        HasMany(x => x.Staff)    
            .Inverse()            
            .Cascade.All();       
        HasManyToMany(x => x.Products)
            .Cascade.All()
            .Table("StoreProduct");    
    }

}

public class EmployeeMap : ClassMap<Employee> 
{

    public EmployeeMap()
    {
        Id(x => x.Id);                
        Map(x => x.FirstName);
        Map(x => x.LastName);
        References(x => x.Store);    
    }
}

EDIT1:

    private void btnDeleteEmployee_MouseDown(object sender, MouseEventArgs e)
    {
        var item = bsEmployees.Current;    // BindingSource
        Employee emp = new Employee();

        if (item.GetType() == emp.GetType())
        {
           emp = (Employee)bsEmployees.Current;
           EmployeeRepository.Delete(emp);
        }            
    }


To fix the cascades that you don't seem to want, change the mapping to Cascade.None

For a quick fix to the stale state do something like:

private void btnDeleteEmployee_MouseDown(object sender, MouseEventArgs e)
{
    if (item.GetType() == emp.GetType())
    {
       emp = EmployeeRepository.GetById(((Employee)beEmployees.Current).Id);
       EmployeeRepository.Delete(emp);
    }            
}

It's a horrible design but maybe enough to get you to a better one after you get past the error.

HTH,
Berrryl


The likely cause of this exception was that the repository method was not able to handle (reject) transient entities, and perhaps also that detached entities were not attached to the session. So the code below fixed that, and avoided the StaleStateExceptions.

Still, as pointed out, this short session scope is for most cases not a good solution.

    public static void Delete(Employee employee)
    {
        using (ISession session = FNH_Manager.OpenSession())
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                if (Employee.Id != 0)
                {
                  var emp =  session.Get(typeof(Employee), employee.Id);

                  if (emp != null)
                  {
                    session.Delete(emp);
                    transaction.Commit();
                  }
                }
            }
        }
    } 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜