2010-11-03 73 views
0

這裏的Currious行爲。如果我創建一個新的HashCode,保存HashCode,然後將事務添加到Transactions集合,級聯在更新上失敗。 Transaction對象不會出現在數據庫中,並且,奇怪的是,HashCode對象的屬性也不會更新!NHibernate的集合:更新不會級聯

我不知道可能是什麼原因造成的。下面是相關映射:

<class name="MyProject.HashCode, MyProject" table="HashCodes"> 
    <id column="Id" name="Id"> 
     <generator class="native" /> 
    </id> 

    <many-to-one name="User" column="UserId" class="MyProject.User, MyProject" /> 
    <property name="Hash" /> 
    <property name="PasswordHash" /> 
    <property name="InitialValue" update="false" /> 
    <property name="CurrentValue" update="true" /> 
    <property name="ClaimedDate" /> 
    <property name="ClaimId" column="RowGuid" generated="insert" /> 

    <bag name="Transactions" table="Transactions" cascade="all" inverse="true"> 
     <key column="HashCodeId" /> 
     <many-to-many column="Id" class="MyProject.Transaction, MyProject" /> 
    </bag> 
</class> 

<class name="MyProject.Transaction, MyProject" table="Transactions"> 
    <id column="Id" name="Id"> 
     <generator class="native" /> 
    </id> 

    <many-to-one name="HashCode" column="HashCodeId" class="MyProject.HashCode, MyProject" /> 
    <property name="AmountCharged" /> 
    <property name="AmountBilled" /> 
    <property name="PreviousBalance" /> 
    <property name="Memo" /> 
    <property name="TransactionDate" generated="insert" update="false" /> 
</class> 

這裏是失敗的,太考驗的情況下,如果它是相關的:

[Test] 
public void TransactionsCascadeWhenUpdatingHashCodes() 
{ 
    var user = TestFactory.CreateUser(); 
    var hashCode = TestFactory.CreateHashCode(user); 

    var transaction = new Transaction 
    { 
     AmountBilled = hashCode.CurrentValue, 
     AmountCharged = decimal.Subtract(hashCode.CurrentValue, decimal.Multiply(hashCode.CurrentValue, 0.03M)), 
     HashCode = hashCode, 
     Memo = "This is a test", 
     PreviousBalance = hashCode.CurrentValue, 
     TransactionDate = DateTime.Now 
    }; 

    hashCode.Transactions.Add(transaction); 

    // Now try to save it. 
    var hashCodeRepository = new HashCodeRepository(Session); 
    hashCodeRepository.Update(hashCode); 

    // Now see if that transaction is good to go 
    Assert.IsTrue(hashCode.Transactions[0].Id > 0); 

    // See if that transaction got persisted. 
    var loadedTransaction = Session.Load<Transaction>(hashCode.Transactions[0].Id); 
    Assert.IsNotNull(loadedTransaction); 
} 

// The repository method that is called... 
public virtual void Update(TObj obj) 
{ 
    CurrentSession.Update(obj); 
} 

任何人有任何建議或想法?

+1

是什麼hashCodeRepository.Update辦?如果您使用的是工作單元模式,通常不需要這種方法......除非更新將實體附加到會話中。如果實體已連接,只需刷新會話即可。你在做那個嗎? – Iain 2010-11-03 06:37:27

+2

看起來您誤解了session.update的用途 - 這是爲了重新附加分離的實體,而不是傳播更改。 – UpTheCreek 2010-11-03 10:36:27

+0

你的最後一個斷言也有問題,Load不會做你認爲會的事。 Load爲你創建一個代理對象,當你訪問其中一個屬性時,它只會進入數據庫進行水合作用,然後它會拋出一個異常或水合物 - 它永遠不會返回null。你需要使用Session.Get (...) – Gareth 2010-11-03 14:27:47

回答

5

您不會在任何地方沖洗會話。

+0

這超出了本測試案例的範圍......我在SetUp方法中開始一個事務,並在TearDown方法中回滾事務。請注意,即使我提交事務,更改也不會傳播。 – 2010-11-03 16:56:26

+2

對於大多數生成器,在會話刷新之前不會更改。正如UpTheCreek所說,Session.Update(alreadyPersistentEntity)是一個noop。 – 2010-11-03 17:35:49

+0

調用更新不會命中數據庫。我建議你閱讀這個http://martinfowler.com/eaaCatalog/unitOfWork.html。 – Iain 2010-11-03 23:01:50

0

更改更新方法如下:

public virtual void Update(TObj obj) 
{ 
    using (ITransaction tx = CurrentSession.BeginTransaction()) 
    { 
     CurrentSession.SaveOrUpdate(obj); 
     tx.Commit(); 
    } 
}