这个错误在 nhibernate 中是啥意思
Posted
技术标签:
【中文标题】这个错误在 nhibernate 中是啥意思【英文标题】:what does this error mean in nhibernate这个错误在 nhibernate 中是什么意思 【发布时间】:2011-05-23 04:58:51 【问题描述】:出乎意料的是,我在使用 nhibernate 进行大量更新时遇到了这个错误。
行被另一个事务更新或删除(或未保存值映射不正确):[MyDomainObject]
错误中没有其他信息。是否有一些推荐的方法来帮助确定根本问题,或者有人可以更好地解释这个错误表示什么或者是一个症状。
一些附加信息
我查看了对象,所有数据看起来都很好,它有一个 ID,等等。 .
请注意,这是在 asp.net-mvc 网站的单个调用堆栈中运行的,因此我不希望在并发方面存在任何线程问题需要担心。
【问题讨论】:
我遇到了同样的错误。有趣的是,当我将session.SaveOrUpdate(ent)
更改为session.Save(ent)
时,它就解决了。但我不知道为什么:) 已编辑:我发现这个答案表明将 unsaved-value=0 设置为不为 null 可以解决问题。 http://***.com/questions/4804734/do-i-have-to-load-get-an-entity-before-saveorupdate-in-nhibernate
【参考方案1】:
如果您在桌子上有触发器,这可能是原因。在这种情况下,在里面添加
SET ROWCOUNT 0;
SET NOCOUNT ON;
【讨论】:
【参考方案2】:NHibernate 有一个对象,我们称之为theObject
。 theObject.Id
的值为 42
。 NHibernate 注意到对象是脏的。对象的 Id 不同于未保存的值,对于整数主键为零 (0)。因此 NHibernate 发出一条更新语句,但没有更新任何行,这意味着数据库中没有针对 Id
的 42
类型的对象的行。因此,该对象已在 NHibernate 不知情的情况下被删除。这可能发生在另一个事务中(例如,您有线程问题),或者如果某人(或另一个应用程序)使用 SQL 直接针对数据库删除/更改了该行。
另一种可能性是您的未保存值是错误的。例如您正在使用 -1
表示未保存的实体,但您的映射的未保存值为零。这不太可能,因为您的应用程序通常是根据它的声音工作的。如果 unsaved-value 错误,您将无法将任何实体保存到数据库中,因为 NHibernate 本来应该发出 UPDATE
语句,而它应该发出 INSERT
。
【讨论】:
不要认为它是线程问题,因为它在一个调用堆栈中,我收到了这个错误。 . 你只会有一个调用堆栈。如果两个线程竞相更新/删除一个对象,一个将获胜(无异常或调用堆栈),另一个将失败(产生调用堆栈异常)。 ASP.NET 本质上是多线程的,尽管每个请求的执行都假象它是唯一运行的线程。 如果有多个浏览器尝试同时进行更新,这只会是一个问题吗?此外,更新了问题以表明数据看起来不错... 只要提交了多个影响相同数据的请求,这就会成为问题。多个请求可以由多个浏览器生成,在一个页面上点击刷新,同一页面的多个 AJAX 请求,......有很多不同的方式可以发生这种情况。我建议实施一些日志记录来追踪错误。【参考方案3】:您说您的数据没问题,但请检查您是否将 ID 映射为自行生成。我遇到了完全相同的问题,但我发送的对象的 ID 不是 0。
希望对你有帮助!
【讨论】:
【参考方案4】:我的问题是这样的:
[Bind(Include="Name")] EventType eventType
应该是:
[Bind(Include="EventTypeId,Name")] EventType eventType
正如其他答案表明 nhibernate 使用零作为我的实体的 id。
【讨论】:
【参考方案5】:一个旧帖子,但希望我的信息可以帮助某人。我得到了一个类似的错误,但只有在我添加了一个新对象之后,才坚持关联。错误的形式是:
NHibernate.StaleObjectStateException:行已被另一个事务更新或删除(或未保存值映射不正确)[My.Entity#0]
注意最后的零,这是我的标识符属性。它不应该尝试使用密钥零保存,因为我在 SQL Server 中使用标识规范(生成器 class=native)。我没有更改 xml 中的未保存值,所以我不知道问题出在哪里;出于某种原因,NHibernate 试图使用键值作为 0 进行更新,而不是为我的新对象保存(并获取下一个键标识)。
最后我发现原因是我在构造函数中将新对象的版本号初始化为 1!即使我的标识符属性为零,由于某种原因,NHibernate 也在寻找版本属性为零,以将其标识为未保存的瞬态实例。 《NHibernate in Action》这本书在第 120 页确实提到了这一点,但由于某种原因,我的对象在正常保持版本号 1 时很好,并且只有在通过关联保存新对象时才会失败。
所以请确保您没有设置您的版本值(保留为零或空)。
【讨论】:
你在哪里设置版本号?【参考方案6】:这意味着您有多个事务访问相同的数据,从而产生并发问题。您应该改进数据访问处理,您可能正在从多个线程更新数据,将更改的数据联合到一个队列中,该队列首先处理对数据库的所有访问。
【讨论】:
嗯,对服务器的不同 http 请求在它们自己的线程中运行,因此仍然可能存在问题。詹姆斯的回答可能会提出解决方案,因为错误也可能出现在映射代码中。以上是关于这个错误在 nhibernate 中是啥意思的主要内容,如果未能解决你的问题,请参考以下文章
通过 NHibernate 检索/保存链接到其他实体的日志条目的最佳方法是啥?