我在使用一些 NHibernate 代码时遇到了问题。基本上,我试图使 session 生命周期尽可能短,以最大限度地减少应用程序中的状态信息。
我发现在不具体的情况下很难描述我的问题,所以我将继续使用文章和类别隐喻。
public class Article
{
public virtual long Id { get; set; }
public virtual string Name { get; set; }
public virtual Category Category { get; set; }
}
public class Category
{
public virtual long Id { get; set; }
public virtual string Name { get; set; }
public override string ToString() { return "cat-" + this.Id.ToString(); }
}
public class ArticleMapping : ClassMap<Article>
{
public ArticleMapping()
{
this.Id( x => x.Id, "id" ).GeneratedBy.Assigned();
this.Map( x => x.Name, "name" );
this.References( x => x.Category ).Fetch.Join().Cascade.None();
}
}
public class CategoryMapping : ClassMap<Category>
{
public CategoryMapping()
{
this.ReadOnly();
this.Id(x => x.Id, "id").GeneratedBy.Assigned();
this.Map(x => x.Name, "name");
}
}
我所做的是创建一个新的文章,为其命名,从通过下面描述的方法加载的列表中分配一个类别并尝试保存。
我收到以下警告:
Unable to determine if cat-1 with assigned identifier is transient or detached
如果您查看模型和映射代码,您会发现 cat-1 根本不应该被持久化 - 它是一个类别并定义为只读和非级联。
//code that loads the list of categories
IStatelessSession session = this.SessionService.GetStatelessSession();
IList<Category> cats = session.CreateCriteria<Category>().List<Category>();
this.SessionService.EndSession(session);
//code that's called to save the instance
ISession session = this.SessionService.GetSession();
using (ITransaction transaction = session.BeginTransaction())
{
session.SaveOrUpdate(article);
transaction.Commit();
}
this.SessionService.EndSession(session);
如果我再次调用 Save 方法,一切都会变成香蕉状:
异常(exception):
NHibernate.StaleStateException: Unexpected row count: 0; expected: 1
堆栈跟踪:
在 NHibernate.AdoNet.Expectations.BasicExpectation.VerifyOutcomeNonBatched(Int32 rowCount,IDbCommand 语句) 在 NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation 期望)
在NHibernate.Persister.Entity.AbstractEntityPersister.Update(对象id,对象[]字段, 对象[] oldFields、对象 rowId、 bool [] includeProperty、Int32 j、对象 oldVersion、对象 obj、SqlCommandInfo sql、ISessionImplementor session )
在NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(对象id,对象[]字段,对象[] oldFields,对象rowId, bool [] includeProperty,Int32 j,对象oldVersion,对象obj,SqlCommandInfo sql,ISessionImplementor session )
在 NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFieldA 类型“NHibernate.StaleStateException”的第一次机会异常发生在 NHibernate.dll 中 s, bool 值 hasDirtyCollection,对象 [] oldFields,对象 oldVersion,对象 obj,对象 rowId,ISessionImplementor session )
在 NHibernate.Action.EntityUpdateAction.Execute()
在 NHibernate.Engine.ActionQueue.Execute(IExecutable 可执行文件)
在NHibernate.Engine.ActionQueue.ExecuteActions(IList列表)
在 NHibernate.Engine.ActionQueue.ExecuteActions()
在NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session )
我曾经认为 NHibernate 没有黑魔法,但这让我想拜访我的巫毒牧师,向另一个领域寻求帮助......
有人知道 StaleStateException 是从哪里来的吗?这次我哪里做错了?
提前致谢
塞比
最佳答案
不确定,但问题可能是您使用一个 session 加载对象,并使用另一个 session 更新它。
在这种情况下,该对象确实是分离的。
尝试使用 Bind() 函数将对象绑定(bind)到第二个 session ,或者考虑仅使用一个 session (请注意, session != 数据库连接。含义 - 打开一个 session 应该不会太昂贵,而且不是一个坏主意) .
关于c# - NHibernate : unexpected session trouble when persisting object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5501223/