2014-02-21 19 views
0

我使用NHibernate版本3.1.0.4000和hbm映射文件。 當我有一個包含袋子集合的實體,並且我將所有物品添加到袋子中的實體保存後,它將保存所有收集物品。但是,當我隨後(在初始保存之後)向集合中添加另一個項目並保存實體時,它不會將新項目保存在集合中。我查看了由NHibernate生成的SQL,它創建了初始的Insert SQL語句,但它不創建Update SQL語句來更新外鍵值。解決方案中的所有行李都會出現此問題。NHibernate添加到包集合中的新項目在更新父實體時不會保存

這裏是一個映射提取物:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        default-lazy="false" 
        namespace="some_namespace" 
        assembly="some_assembly"> 

    <class name="Landing" 
      table="[Landing]" 
      select-before-update="true" 
      optimistic-lock="version"> 
    <id name="Id" 
     column="[Id]" 
     unsaved-value="null"> 
     <generator class="assigned" /> 
    </id> 

    <version name="Version" 
      column="[Version]" 
      unsaved-value="null" /> 

    <bag name="LandingPermits" 
     cascade="all-delete-orphan" 
     access="field.camelcase"> 
     <key column="[LandingId]" /> 
     <one-to-many class="LandingPermit" /> 
    </bag> 

    </class> 
</hibernate-mapping> 

這裏是我的NHibernate庫保存方法:

public NHibernateRepository(ISessionFactory factory, string queriesAssemblyName = null, string clientName = null) 
{ 
    this.sessionFactory = factory; 
    this.queriesAssemblyName = queriesAssemblyName; 
    this.clientName = clientName; 

    if (!string.IsNullOrEmpty(this.queriesAssemblyName)) 
     LoadQueries(); 
} 

public virtual void Save(IAggregateRoot entity) 
{ 
    Save(new IAggregateRoot[] { entity }); 
} 

public virtual void Save(IAggregateRoot[] entities) 
{ 
    try 
    { 
     using (var session = OpenSession()) 
     { 
      using (var transaction = session.BeginTransaction()) 
      { 
       try 
       { 
        foreach (var entity in entities) 
        { 
         if (entity.IsNew) 
          entity.AddedDateTime = DateTime.Now; 
         else 
          entity.UpdatedDateTime = DateTime.Now; 

         session.SaveOrUpdate(entity.GetType().Name, entity); 
        } 
        transaction.Commit(); 
       } 
       catch (Exception e) 
       { 
        transaction.Rollback(); 
        throw e; 
       } 
       finally 
       { 
        if (session.Connection.State == ConnectionState.Open) 
         session.Connection.Close(); 

        session.Connection.Dispose(); 
        session.Close(); 
       } 
      } 
     } 
    } 
    catch (GenericADOException e) 
    { 
     var sqlException = e.InnerException as SqlException; 

     if ((sqlException != null) && (sqlException.Number == ForeignKeyExceptionNumber)) 
      throw new EntityInUseException("Save", sqlException); 
     else 
      throw new RepositoryException("Save", e.InnerException); 
    } 
    catch (StaleObjectStateException e) 
    { 
     throw new ConcurrencyException("Save", e, new Identity((Guid?)e.Identifier)); 
    } 
    catch (Exception e) 
    { 
     throw new RepositoryException("Save", e); 
    } 
} 

我已經嘗試了一些東西,包括逆屬性設置爲true,但沒有成功。 希望這是足夠的信息,任何人assistist。 謝謝

回答

0

如果您的收藏是inverse=false(默認),這意味着集合的所有者(父母)負責關係。 在上面的代碼中,如果父代和子代都是IAggregateRoot,但是如果它們都是這樣,那麼意味着當您將孩子保存在不知道父代的會話中時,該孩子將保存的很好,但不會保留被添加到集合中。如果您使用inverse=true,孩子將負責關係。在這種情況下,模型應該是雙向的,你應該映射兩端。

你這裏有幾個選項...

  • 是孩子真正的總根源在哪裏?也許它應該和它的父母一起堅持下去?
  • 使用雙向關係,並使用inverse=true
+0

感謝您的迴應羅傑。 在我的情況下,孩子(LandingPermit)不是IAggregateRoot –

相關問題