Я пытаюсь сохранить объект с несколькими отношениями 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);
}
Каково было ваше альтернативное сопоставление (с каскадом HasMany)? Кроме того, GetExpanseReports и GetTimeWorked возвращают существующие данные? Не подключен к любому счету? –
Mr Mush: При сопоставлении счетов я попробовал 'Cascade.SaveUpdate()' для 'ExpenseReports' и' BilledTime'. Методы Get возвращают существующие данные, которые еще не были привязаны к счету. Однако в приведенном выше коде 'invoice.AddExpenseReport (erList)' влияет на сам счет. Следующий метод, вызывающий 'GetTimeWorked()', получает объекты TimeWorked без указания счета-фактуры, но почему-то NHB недовольна тем, что 'invoice' был изменен. – leahcimp
Не могли бы вы попытаться получить списки перед созданием нового счета-фактуры и подключением их после создания счета-фактуры? Возможно, возникла проблема с идентификатором счета по умолчанию. –