在尝试将对象与其子节点一起保存时,NHibernate会抛出
System.ObjectDisposedException: 'Cannot access a disposed object.'
调用tx.Commit()
时。
奇怪的数据仍然存在于数据库表中。
我的NHibernate会话通过
与Web请求绑定 if (!CurrentSessionContext.HasBind(sessionFactory))
CurrentSessionContext.Bind(sessionFactory.OpenSession());
我正在使用ASP.NET MVC 5,NHibernate 4.1,(虽然不使用流畅的NHibernate)
以下是产生错误的代码:
代码:
ISession session = SessionFactory.GetCurrentSession();
session.SetBatchSize(1000);
using (var tx = session.BeginTransaction())
{
try
{
IList<Bar> barList = session.QueryOver<Bar>().Where(b => b.IsEnabled == true).List();
foreach (Bar bar in barList)
{
var foo = new Foo { BarObj = bar };
foo.BarDetailList = new HashSet<BarDetail>();
foreach (Alpha alpha in bar.AlphaList)
{
foreach (Beta beta in alpha.BetaList)
{
foo.BarDetailList.Add(
new BarDetail { ParentFoo = foo, AlphaObj = alpha, BetaObj = beta }
);
}
}
session.Persist(foo); // Save gives same result
}
tx.Commit(); // This line throws the ObjectDisposedException
}
catch (Exception ex)
{
// details omitted
tx.Rollback();
}
}
课程定义:
public class BarDetail : AuditableModelBase
{
public virtual Foo ParentFoo { get; set; }
public virtual Alpha alpha { get; set; }
public virtual Beta beta { get; set; }
public virtual IList<BarMonthlyDetail> MonthlyDetailList { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
var barDetail = obj as BarDetail;
if (barDetail == null)
return false;
if (barDetail.Id.HasValue && barDetail.Id == this.Id)
return true;
else
{
// If id is null, then look for other members used when adding
// BarDetail objects as child objects at the time of creation of forecast
// otherwise they wont get added
if (this.alpha != null && barDetail.alpha != null && this.alpha.Id == barDetail.alpha.Id
&& this.beta != null && barDetail.beta != null && this.beta.Id == barDetail.beta.Id)
return true;
}
return base.Equals(obj);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + Id.GetHashCode();
return hash;
}
}
}
public class BarMonthlyDetail : AuditableModelBase
{
public virtual BarDetail ParentBarDetail { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
var barMonthlyDetail = obj as BarMonthlyDetail;
if (barMonthlyDetail == null)
return false;
if (barMonthlyDetail.Id == this.Id)
return true;
return base.Equals(obj);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + Id.GetHashCode();
return hash;
}
}
}
public class Bar : AuditableModelBase
{
public Bar()
{
}
public virtual ISet<UserAccount> Users { get; set; }
public virtual ISet<Alpha> alphas { get; set; }
public virtual ISet<Beta> betas { get; set; }
public override string ToString()
{
return Name ?? "";
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
var bar = obj as Bar;
if (bar == null)
return false;
if (bar.Id == this.Id)
return true;
return base.Equals(obj);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + Id.GetHashCode();
//hash = hash * 23 + (Name ?? "").GetHashCode();
//hash = hash * 23 + (Code ?? "").GetHashCode();
return hash;
}
}
}
public class Foo : AuditableModelBase
{
public virtual Bar bar { get; set; }
public virtual IList<BarDetail> BarDetailList { get; set; }
public override string ToString()
{
return Name ?? "";
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
var foo = obj as Foo;
if (foo == null)
return false;
if (foo.Id == this.Id)
return true;
return base.Equals(obj);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + Id.GetHashCode();
return hash;
}
}
}
public class Alpha : AuditableModelBase
{
public virtual ISet<Bar> bars { get; set; }
public virtual ISet<Beta> betas { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
var alpha = obj as Alpha;
if (alpha == null)
return false;
if (alpha.Id == this.Id)
return true;
return base.Equals(obj);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + Id.GetHashCode();
return hash;
}
}
}
public class Beta : AuditableModelBase
{
public virtual Bar bar { get; set; }
public virtual Alpha alpha { get; set; }
public override string ToString()
{
return Name ?? "";
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
var beta = obj as Beta;
if (beta == null)
return false;
if (beta.Id == this.Id)
return true;
return base.Equals(obj);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + Id.GetHashCode();
return hash;
}
}
}
映射:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Core" namespace="DataAccess.Models">
<class name="BarDetail" table="BarDetail">
<id name="Id">
<generator class="identity"/>
</id>
<property name="IsEnabled" not-null="true"/>
<many-to-one name="ParentFoo" class="Foo" column="FooId" not-null="true"/>
<many-to-one name="alpha" class="Alpha" column="AlphaId" not-null="true"/>
<many-to-one name="beta" class="Beta" column="BetaId" not-null="true"/>
<bag name="MonthlyDetailList" table="BarMonthlyDetail" lazy="true" cascade="save-update" order-by="Month asc" >
<key>
<column name="BarDetailId" not-null="true"/>
</key>
<one-to-many class="BarMonthlyDetail"/>
</bag>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Core" namespace="DataAccess.Models">
<class name="BarMonthlyDetail" table="BarMonthlyDetail">
<id name="Id">
<generator class="identity"/>
</id>
<property name="Month" />
<many-to-one name="ParentBarDetail" class="BarDetail" column="BarDetailId" not-null="true"/>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Core" namespace="DataAccess.Models">
<class name="Foo" table="Foo">
<id name="Id">
<generator class="identity"/>
</id>
<many-to-one name="bar" class="Bar" column="BarId" not-null="true"/>
<bag name="BarDetailList" table="BarDetail" lazy="true" cascade="save-update">
<key>
<column name="FooId" not-null="true"/>
</key>
<one-to-many class="BarDetail"/>
</bag>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Core" namespace="DataAccess.Models">
<class name="Beta" table="Beta">
<id name="Id">
<generator class="identity" />
</id>
<property name="IsEnabled" not-null="true"/>
<many-to-one name="bar" class="Bar" column="BarId" not-null="true" />
<many-to-one name="alpha" class="Alpha" column="AlphaId" not-null="true" />
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Core" namespace="DataAccess.Models">
<class name="Alpha" table="Alpha">
<id name="Id">
<generator class="identity" />
</id>
<set name="alphas" table="AlphaBar" lazy="true">
<key column="AlphaId" not-null="true"/>
<many-to-many class="Bar" column="BarId"/>
</set>
<set name="betas" table="Beta" lazy="true" inverse="true">
<key column="BarId" not-null="true"/>
<one-to-many class="Beta" />
</set>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Core" namespace="DataAccess.Models">
<class name="Bar" table="Bar">
<id name="Id">
<generator class="identity" />
</id>
<set name="Users" table="UserBar" inverse="true" lazy="true">
<key column="BarId"/>
<many-to-many class="UserAccount" column="UserId"/>
</set>
<set name="alphas" table="AlphaBar" inverse="true" lazy="true">
<key column="BarId"/>
<many-to-many class="Alpha" column="AlphaId"/>
</set>
<set name="betas" table="Beta" lazy="true" inverse="true">
<key column="BarId" not-null="true"/>
<one-to-many class="Bar" />
</set>
</class>
</hibernate-mapping>
我试图寻找类似的SO帖子(例如This)和/或web但这个问题似乎有所不同
更新:我之前尝试过显式设置刷新模式session.FlushMode = FlushMode.Commit;
,它已设置为Auto
但错误仍然存在
答案 0 :(得分:0)
我摆脱了错误。当我将<ul class="vc_tta-tabs-list">
<li class="vc_tta-tab">
<a href="#ID-element-1">Tab 1</a>
</li>
<li class="vc_tta-tab">
<a href="#ID-element-2">Tab 2</a>
</li>
<li class="vc_tta-tab">
<a href="#ID-element-3">Tab 3</a>
</li>
<li class="vc_tta-tab">
<a href="#ID-element-4">Tab 4</a>
</li>
</ul>
<div class="vc_tta-panel" id="ID-element-1">SOME TEXT 1</div>
<div class="vc_tta-panel" id="ID-element-2">SOME TEXT 2</div>
<div class="vc_tta-panel" id="ID-element-3">SOME TEXT 3</div>
<div class="vc_tta-panel" id="ID-element-4">SOME TEXT 4</div>
更改为Set
并仅在Bag
上使用GetHashCode()
方法时,我使用了Id
,它开始正常工作。