代码之家  ›  专栏  ›  技术社区  ›  gilles27

插入实体后出现“空标识符”异常

  •  5
  • gilles27  · 技术社区  · 15 年前

    我无法将实体保存到SQL Server 2005数据库中。我正在使用NHibernate 2.0.0.3002作为持久层。映射是典型的,具有整数ID,如下所示

    <id name="Id" unsaved-value="0">
      <column name="Id"/>
      <generator class="identity" />
    </id>
    

    为了简洁起见,我省略了其余的部分。应用程序使用的存储库类具有以下通用保存方法

    public void Save(T toSave)
    {
        Save(new T[] { toSave });
    }
    
    public void Save(IEnumerable<T> toSave)
    {
        using (ISession session = SessionFactory.OpenSession())
        {
            foreach (T item in toSave)
            {
                session.SaveOrUpdate(item);
            }
            session.Flush();
        }
    }
    

    在会话上调用saveorupdate时,会引发一个异常,并显示一条消息“空标识符”。当我检查数据库时,该行已经插入了所有正确的值,所以我认为问题在于nhibernate试图用@@id entity返回的值设置实体的id属性。我可以通过SQL事件探查器看到正在调用@@Identity,所以我不明白为什么会引发异常。

    其他人有这个问题吗?

    5 回复  |  直到 11 年前
        1
  •  8
  •   Ben    15 年前

    保存和删除都必须发生在事务中,并且事务必须在结束时提交。

    像这样:

    public void Save(IEnumerable<T> toSave)
    {
        using (ISession session = SessionFactory.OpenSession())
        {
            ITransaction transaction = Session.BeginTransaction();
    
            foreach (T item in toSave)
            {
                session.SaveOrUpdate(item);
            }
    
            transaction.Commit();           
            session.Flush();
        }
    }
    

    请注意:您需要将其包装在using中并正确回滚…此外,根据您的场景,在何处打开和提交事务也很重要。您还应该在完成后关闭事务…

    另外,您能详细说明在哪里发生了异常吗?听起来您正在保存一个父级,然后因为父级的ID为空而引发子级?或者,它真的在拯救父母吗?

        2
  •  1
  •   Frederik Gheysels    15 年前

    配置log4net以便记录和查看nhibernate正在执行的操作可能会有所帮助…

    我曾经也遇到过使用access的nhibernate的问题,并且可以通过设置日志来解决问题,这样我就可以准确地找出问题的原因。

    我收到的错误消息与您的不同,但是 this 这篇文章是我描述如何解决我的问题的。也许你能帮上忙。:)

        3
  •  0
  •   Shane Courtrille    15 年前

    NHibernate的开发人员非常不鼓励身份识别。我们遇到的主要问题是,在你冲洗之前,你得不到身份证。在你的国际案件中,hilo会是一个很好的替代品。

    我想你真的想这么做…

    <id name="Id" column="Id" unsaved-value="0">
       <generator class="identity"/>  
    </id>
    
        4
  •  0
  •   Chris Smith    12 年前

    我也有这个错误,解决方法是将它包装在本提到的事务中。然而,我不能让本和吉列的代码工作-可能是因为我对仿制药和NHibernate不熟悉。我创建了一个稍有不同的实现(使用Fluent NHibernate v1.3):

            public static ISession LocalDbSession = null;
    
        public static void Save<T>(T toSave)
        {
            using (var transaction = LocalDbSession.BeginTransaction())
            {
                LocalDbSession.Save(toSave);
                transaction.Commit();
                LocalDbSession.Flush();
            }
        }
    
        public static void Save<T>(IEnumerable<T> toSave)
        {
            using (var transaction = LocalDbSession.BeginTransaction())
            {
                foreach (T item in toSave)
                {
                    LocalDbSession.Save(item);
                }
    
                transaction.Commit();
                LocalDbSession.Flush();
            }
        }
    
        5
  •  -2
  •   alice7    15 年前

    我认为不是生成器class=“identitiy”/>

    尝试generator class=“guid.comp”