NHibernate:对象引用未保存的瞬态实例

时间:2014-01-06 13:33:18

标签: c# nhibernate fluent-nhibernate

当我尝试将对象添加到存储库时,我会收到带有消息的NHibernate.TransientObjectException

  

对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例,或者将属性的级联操作设置为使其自动保存的事件。   键入:MyApp.Domain.Model.Task

我用:

  • NHibernate 3.3.1
  • FluentNHibernate 1.4
  • Microsoft Unity 2.1.505

存储库中的方法或多或少如下(我在这里提出合并版本):

public void Add(T item)
{
    if (!GetSession().Query<T>().Contains(item)) //generates the error, if commented out works fine
    {
        try
        {
            GetSession().BeginTransaction();
            GetSession().Save(item);
            GetSession().CommitTransaction();
        }    
        catch
        {
            //rollback code
        }
    }
}

重要的是我尝试在存储库中保存的对象没有任何对其他对象的引用和/或关系。这是一个相当简单的实体。 值得一提的是,它扩展了具有Guid类型ID的DomainObject。

我使用Code First架构,因此我的数据库是根据我的代码生成的。 由于继承(每个实体扩展DomainObject),我使用UseUnionSubclassForInheritanceMapping()

整个堆栈跟踪如下:

   w NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(String entityName, Object entity, ISessionImplementor session)
   w NHibernate.Type.EntityType.GetIdentifier(Object value, ISessionImplementor session)
   w NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand cmd, Object value, Int32 index, ISessionImplementor session)
   w NHibernate.Param.NamedParameterSpecification.Bind(IDbCommand command, IList`1 multiSqlQueryParametersList, Int32 singleSqlParametersOffset, IList`1 sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session)
   w NHibernate.Param.NamedParameterSpecification.Bind(IDbCommand command, IList`1 sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session)
   w NHibernate.SqlCommand.SqlCommandImpl.Bind(IDbCommand command, ISessionImplementor session)
   w NHibernate.Loader.Loader.PrepareQueryCommand(QueryParameters queryParameters, Boolean scroll, ISessionImplementor session)
   w NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
   w NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
   w NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)
   w NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters)
   w NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes)
   w NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters)
   w NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters)
   w NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results)
   w NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results)
   w NHibernate.Impl.AbstractSessionImpl.List(IQueryExpression queryExpression, QueryParameters parameters)
   w NHibernate.Impl.ExpressionQueryImpl.List()
   w NHibernate.Linq.DefaultQueryProvider.ExecuteQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery)
   w NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
   w NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
   w System.Linq.Queryable.Contains[TSource](IQueryable`1 source, TSource item)
   w MyApp.Data.Nhibernate.Fluent.Repository`1.Add(T item) w f:\Projects\MyApp\MyApp.Data.Nhibernate.Fluent\Repository.cs:wiersz 75
   w MyApp.Domain.Services.Impl.CatalogServices.CreateTask(Task task) w f:\Projects\MyApp\MyApp.Domain.Services\Impl\CatalogServices.cs:wiersz 51

感谢您的帮助

最诚挚的问候, 塞巴斯蒂安

1 个答案:

答案 0 :(得分:3)

您根本无法查询未分配的对象,因为它没有分配ID。

要查询该实体,NHibernate将尝试找出实体的ID。这仅适用于保存的已保存或瞬态对象。

未保存的实体没有设置ID。因此,如果ID的类型是int,则value将为零。在你的情况下,我猜它将是Guid.Empty,因为Guid不能为空。只需检查一下。

您还可以将映射中的unsafed值定义为100%确定;)。但它也应该默认使用Guid或int。映射可用于自定义类型等...

Id(x => x.Id).UnsavedValue(0);
相关问题