0

当我尝试在我正在处理的 MVC 2 项目中使用关联的姓氏列表保存客户时,我遇到了 NHibernate 抛出 TransientObjectException 的问题。

这是类的代码:

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; }
}

我正在使用 Fluent 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) %>

单击 Save Changes 按钮调用控制器上的一个方法,该方法将客户传递回存储库,该存储库调用 ISession 上的 Update 方法。这是 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)
4

1 回答 1

0

尝试调用 ISession.SaveOrUpdate

于 2012-07-09T16:43:57.790 回答