2012-07-09 38 views
0

我在嘗試在我正在工作的MVC 2項目中使用關聯的家族名稱列表保存客戶時拋出TransientObjectException上。在ASP.NET MVC中保存對象時引發NHibernate.TransientObjectException 2

這是類代碼:

public class Customer 
{ 
    public virtual Guid Id { get; set; } 
    public virtual int Version { get; set; } 
    public virtual string Forename { get; set; } 
    public virtual IList<FamilyName> FamilyNames { get; set; } 
} 
public class FamilyName 
{ 
    public virtual Guid Id { get; set; } 
    public virtual int Version { get; set; } 
    public virtual string Name{ get; set; } 
    public virtual bool IsCurrent { get; set; } 
    public virtual Patient Patient { get; set; } 
} 

我使用功能NHibernate的持久性和映射是這樣的:

public CustomerMap() 
{ 
    Table("Customers"); 
    Id(x=>x.Id).GeneratedBy.GuidComb(); 
    Version(x => x.Version); 
    Map(x => x.Forename).Not.Nullable(); 
    HasMany(x => x.FamilyNames) 
    .Inverse() 
    .Cascade.All(); 
} 


public FamilyNameMap() 
{ 
    Table("FamilyNames"); 
    Id(x=>x.Id).GeneratedBy.GuidComb(); 
    Version(x => x.Version); 
    Map(x => x.Name).Not.Nullable(); 
    Map(x => x.IsCurrent).Not.Nullable(); 
    References(x => x.Patient).Not.Nullable(); 
} 

我有一個強類型EditCustomerDetails與查看其中的代碼如下:

<% using (Html.BeginForm("SaveChanges", "CustomerDetails")) { %> 
<input type="submit" value="Save changes"/> 
<%= Html.HiddenFor(customer => customer.Id) %> 
<%= Html.HiddenFor(customer => customer.Version) %> 
    <label>Forename:</label> 
    <%= Html.TextBoxFor(customer => customer.Forename)%> 
    <label>Family Names</label> 
    <div class="familyNames"> 
    <%= Html.EditorFor(customer => customer.FamilyNames)%> 
    </div> 
<% } %> 

這是自定義編輯器模板對於FamilyName類:

<%= Html.HiddenFor(name => name.Id) %> 
<%= Html.HiddenFor(name => name.Version) %> 
<%= Html.HiddenFor(name => name.Patient.Id) %> 
<label>Name:</label> 
<%= Html.TextBoxFor(name => name.Name) %> 
<label>Is Current?:</label> 
<%= Html.CheckBoxFor(name =>name.IsCurrent) %> 

點擊保存更改按鈕調用其傳遞迴客戶,其呼籲的Isession更新方法的存儲庫中的控制器上的方法。這就是NHibernate.TransientObjectException拋出的消息「對象引用一個未保存的瞬態實例 - 在刷新之前保存瞬態實例」。

我不知道爲什麼會發生這種情況。我已經加入了代碼,所有數據都從視圖中正確地傳回,所有對象都具有正確的屬性值。我已經能夠找到解決這個問題的唯一建議,就是在映射中設置Cascade.All,這正是我所做的。

任何想法?

編輯:這是錯誤消息:

ERROR Shipping.Web.Filters.UnhandledErrorAttribute - An unhandled exception has occurred 
Shipping.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing. Type: Shipping.Domain.Entities.Customer, Entity: Haemoglobinopathy.Domain.Entities.Customer 
    at NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(String entityName, Object entity, ISessionImplementor session) 
    at NHibernate.Type.EntityType.GetIdentifier(Object value, ISessionImplementor session) 
    at NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) 
    at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) 
    at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) 
    at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) 
    at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session) 
    at NHibernate.Action.EntityUpdateAction.Execute() 
    at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) 
    at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) 
    at NHibernate.Engine.ActionQueue.ExecuteActions() 
    at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) 
    at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) 
    at NHibernate.Impl.SessionImpl.Flush() 
    at NHibernate.Transaction.AdoTransaction.Commit() 
    at Haemoglobinopathy.Persistence.TransactionAttribute.OnActionExecuted(ActionExecutedContext filterContext) in C:\dev\Projects\Haemoglobinopathy\Haemoglobinopathy.Persistence\TransactionAttribute.cs:line 26 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
    at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<>c__DisplayClassf.<InvokeActionMethodWithFilters>b__c() 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
    at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<>c__DisplayClassf.<InvokeActionMethodWithFilters>b__c() 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) 
+0

這不是重複。這個問題是關於另一個例外。 – Babakoto 2012-07-09 17:20:31

+0

你是對的,對不起。 – 2012-07-09 17:21:45

+0

這可能與將實際實體用作ViewModels有關。您的控制器將收到由MVC創建的實體,但未從會話獲得。創建實際的ViewModel通常更安全,然後將實體同步到實際需要更新的實體上,而不是整個實體(因爲您的視圖可能不會回發整個實體)。 – 2012-07-09 17:30:35

回答

0

嘗試調用ISession.SaveOrUpdate

+0

謝謝,但我只是試了一下,它仍然會拋出同樣的異常 – Babakoto 2012-07-09 16:50:56