1

Я пытаюсь сохранить объект с несколькими отношениями HasMany, и я получаю исключение: «объект ссылается на несохраненный объект переходный экземпляр - сохранить временный экземпляр перед промывкой ».Объект NHibernate Exception «ссылается на несохраненный экземпляр переходного процесса - сохраняет временный экземпляр перед промывкой» при сохранении объекта с HasMany

Ниже приведены мои упрощенные классы, их соответствующие сопоставления и мой «прикладной» код.

В разделе «Код приложения» показано, что я хочу сделать: добавить отчеты о расходах и время, потраченное на счет-фактуру, а затем сохранить счет-фактуру.

Однако исключение встречается в GetTimeWorked(). Если я отменил порядок (добавьте время, затраченное на отчеты о расходах), тогда ошибка возникает в GetExpenseReports().

Если я сохраню счет-фактуру после добавления отчетов о расходах, а затем сохраните его снова после добавления времени работы, он отлично работает. Однако это сохранение должно быть транзакционным: отчеты о расходах и время работы должны быть сохранены вместе.

Я много читал об этом исключении, но ничего не пытаюсь работать. Ситуации, о которых я читал, кажутся немного отличающимися от этого. Я предполагаю, что это проблема с отображением, и я попробовал некоторое альтернативное сопоставление (на стороне HasMany, с Cascade), но я в недоумении.

Любая идея, что здесь происходит и как я могу ее решить?

Спасибо!

// 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: При сопоставлении счетов я попробовал 'Cascade.SaveUpdate()' для 'ExpenseReports' и' BilledTime'. Методы Get возвращают существующие данные, которые еще не были привязаны к счету. Однако в приведенном выше коде 'invoice.AddExpenseReport (erList)' влияет на сам счет. Следующий метод, вызывающий 'GetTimeWorked()', получает объекты TimeWorked без указания счета-фактуры, но почему-то NHB недовольна тем, что 'invoice' был изменен. – leahcimp

+1

Не могли бы вы попытаться получить списки перед созданием нового счета-фактуры и подключением их после создания счета-фактуры? Возможно, возникла проблема с идентификатором счета по умолчанию. –

ответ

1

Извлеките списки перед созданием нового счета-фактуры, возможно, существует проблема с идентификатором счета-фактуры по умолчанию.

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 поможет. i guess GetExpenses() и GetTimeWorked() Ссылочки, которые приводят к флешу, чтобы получить правильные данные

Смежные вопросы

 Смежные вопросы