1

HasManyの複数の関係を持つオブジェクトを保存しようとしています。一時インスタンス - フラッシュする前に一時インスタンスを保存する "。NHibernate Exception "HasManyでオブジェクトを保存するときに、未保存の一時的なインスタンスを参照するオブジェクトがフラッシングする前に一時的なインスタンスを保存する"

私の単純化されたクラス、対応するマッピングと私の "アプリケーション"コードは以下の通りです。

「アプリケーションコード」セクションには、経費レポートと経費を請求書に追加してから請求書を保存します。

ただし、例外はGetTimeWorked()で発生します。注文を元に戻す(経費報告の前に時間を加算する)と、GetExpenseReports()でエラーが発生します。

費用レポートを追加した後に請求書を保存してから、作業時間を追加してからもう一度保存しても問題ありません。ただし、この保存はトランザクショナルである必要があります。費用レポートと作業時間は一緒に保存する必要があります。

私はこの例外について多くを読んだことがありますが、私は何も試してみません。私が読んだ状況は、これとは多少異なるようです。私はこれがマッピングの問題であると推測しています。(HasMany側で、カスケードを使って)いくつかの代替マッピングを試みましたが、私は迷っています。

ここで何が起こっているのか、それをどのように解決することができますか?

ありがとうございます!

// Classes 
public class TimeWorked { 
    public virtual long Id { get; private set; } 
    public virtual float Hours { get; set; } 
    public virtual Invoice Invoice { get; set; } 
} 

public class ExpenseReport { 
    public virtual long Id { get; set; } 
    public virtual IList<Expense> Expenses { get; set; }     
    public virtual Invoice Invoice { get; set; } 
} 

public class Invoice { 
    public virtual long Id { get; set; } 
    public virtual IList<ExpenseReport> ExpenseReports { get; set; } 
    public virtual IList<TimeWorked> BilledTime { get; set; } 

    public virtual void AddExpenseReport(List<ExpenseReport> expenseReports) 
    { 
     foreach (ExpenseReport er in expenseReports) 
     { 
      ExpenseReports.Add(er); 
      er.Invoice = this; 
     } 
    } 

    public virtual void AddTimeWorked(List<TimeWorked> timeWorked) 
    { 
     foreach (TimeWorked tw in timeWorked) 
     { 
      BilledTime.Add(tw); 
      tw.Invoice = this; 
     } 
    }  
} 

// Mapping 
public class TimeWorkedMapping : ClassMap<TimeWorked> 
{ 
    public TimeWorkedMapping() 
    { 
     Id(x => x.Id); 
     References(x => x.Invoice); 
    } 
} 

public class ExpenseReportMapping : ClassMap<ExpenseReport> 
{ 
    public ExpenseReportMapping() 
    { 
     // Primary Key 
     Id(x => x.Id); 
     HasMany(x => x.Expenses).Cascade.AllDeleteOrphan(); 
      References(x => x.Invoice); 
    } 
} 

public class InvoiceMapping : ClassMap<Invoice> 
{ 
    public InvoiceMapping() 
    { 
     Id(x => x.Id);  
     HasMany(x => x.ExpenseReports).Inverse(); 
     HasMany(x => x.BilledTime).Inverse(); 
    } 
} 


// Application Code 

public class MyPage 
{ 
    // Do stuff... 
    Invoice invoice = new Invoice(); 

    // Add the expense reports      
    List<ExpenseReport> erList = GetExpenseReports(); 
    invoice.AddExpenseReport(erList); 

    // Add billable time 
    List<TimeWorked> twList = GetTimeWorked();  <<== Exception occurs in here 
    invoice.AddTimeWorked(twList); 

    // Save invoice 
    Save(invoice); 

} 
+0

代替マッピング(HasManyカスケードで)は何でしたか?また、GetExpanseReportsとGetTimeWorkedは既存のデータを返しますか?任意の請求書との接続が解除されていますか? –

+0

Mr Mush:Invoiceマッピングで、私は 'ExpenseReports'と' BilledTime'の両方で 'Cascade.SaveUpdate()'を試みました。 Getメソッドは、まだ請求書に割り当てられていない既存のデータを戻します。しかし、上記のコードでは、 'invoice.AddExpenseReport(erList)'はインボイス自体に影響します。次のGetTimeWorked()メソッド呼び出しは、Invoiceを割り当てずにTimeWorkedオブジェクトを取得しますが、 'invoice'が変更されているため、NHBは何らかの理由で不幸です。 – leahcimp

+1

新しい請求書を作成して請求書を作成した後に接続する前にリストを取得できますか?デフォルトの請求書IDに問題がある可能性があります。 –

答えて

1

新しい請求書を作成する前にリストを取得すると、デフォルトの請求書IDに問題がある可能性があります。

List<TimeWorked> twList = GetTimeWorked(); 
List<ExpenseReport> erList = GetExpenseReports(); 
Invoice invoice = new Invoice(); 

// Add the expense reports      
invoice.AddExpenseReport(erList); 

// Add billable time 
invoice.AddTimeWorked(twList); 

// Save invoice 
Save(invoice); 
0

設定セッション.Flushmode == FlushMode.Commitが役立ちます。私は推測GetExpenses()GetTimeWorked()参照正しいデータを得るためにフラッシュする結果の請求書

関連する問題

 関連する問題