首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >对于分离的父实体,NHibernate -级联合并到子实体失败

对于分离的父实体,NHibernate -级联合并到子实体失败
EN

Stack Overflow用户
提问于 2012-12-08 00:27:41
回答 1查看 3.5K关注 0票数 16

Current Approach

在Person web forms应用程序(使用Spring.NET和NHibernate)中,我们有一个聚合根(Person),它的详细信息是跨多个屏幕/页面捕获的。Person实体在进入此工作流之前就已经存在,并且对Person对象图所做的所有更改都是原子的,因此只有在提交最终屏幕时才应该刷新到数据库。

为此,我们首先使用HTTP3.2将Person从数据库加载到第一个页面,然后在分页过程中加载序列化的Person对象图并将其保存到NHibernate会话变量中。

在将人员从HTTP会话中检索出来后,它处于与当前NHibernate会话分离的状态,因此我们通过在当前会话上调用Update()方法来重新附加,如下所示:

代码语言:javascript
复制
var sessionPerson = Session[PersonSessionName] as Person;
var currentSession = SessionFactory.GetCurrentSession();
currentSession.Update(sessionPerson);

注意:使用锁()抛出一个异常,通知“重新关联的对象有脏集合”。

当重新附加时,我们可以像预期的那样遍历对象图,从数据库中提取尚未加载到内存中的子实体的数据。

映射文件的子集

代码语言:javascript
复制
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="false" assembly="Domain" namespace=" TestApp.Domain">
  <class name="Person" table="Person">
    <id name="Id">
      <generator class="TestApp.CustomNHibernateHiLoGenerator, TestApp.Core" />
    </id>
    <property name="Name" not-null="false" />

    <bag name="PersonCountries" access="field.camelcase-underscore" cascade="all-delete-orphan">
      <key column="PersonId" foreign-key="FK_ PersonCountry_Person" not-null="true" />
      <one-to-many class="PersonCountry" />
    </bag>
  </class>

  <class name="Country" table="Country">
    <id name="Id">
      <generator class="TestApp.CustomNHibernateHiLoGenerator, TestApp.Core" />
    </id>
    ... No back reference to Person
  </class>
</hibernate-mapping>

代码语言:javascript
复制
public class PersonCountry : Entity, ICloneable
{
    // No properties of note
}

public class Person : Entity, ICloneable
{
    public virtual string Name { get; set; }
    public virtual IEnumerable<PersonCountry> PersonCountries { get; set; }
    ... 
    // More Properties
}

刷新对数据库的更改

代码语言:javascript
复制
.. // Code-behind
PricingService.Save(ProductContext.Pricing, forceMerge: true);            


public class PricingService : IPricingService
{
   [Transaction]  // Spring.NET transaction
   public Pricing Save(Pricing pricing, bool forceMerge = false)
   {            
      if(forceMerge)
      {
         CurrentSession.Merge(entity);
      }
      else
      {
         CurrentSession.SaveOrUpdate(entity);
      }
   }
}

当需要刷新对数据库的所有更改时,只要我们只更改名称,更改就会按预期工作。但是,向Person添加新的国家/地区项会导致一对多关系上的Merge()的级联失败,并出现以下异常(奇怪的是,删除国家/地区可以很好地工作)。

代码语言:javascript
复制
NHibernate.StaleStateException: Batch update returned unexpected row count from update; actual row count: 0; Expected: 1

任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2012-12-14 04:03:39

每个具有有效Id的实体都被视为持久化的,这就是为什么它试图在merge中更新它,但因为它还没有保存,所以它失败了。在session.Update()之后调用session.Flush()

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13767048

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档