我在将实体保存到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时,会抛出一个带有“null identifier”消息的异常。当我检查数据库时,已插入所有正确值的行,所以我认为问题是当NHibernate尝试使用@@ IDENTITY返回的值设置实体的Id属性时。我可以通过SQL Profiler看到正在调用@@ IDENTITY,所以我不明白为什么会抛出异常。
还有其他人有这个问题吗?
答案 0 :(得分:8)
保存和删除都必须在事务中发生,并且事务必须在最后提交。
像这样: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();
}
}
请注意:您希望将其包含在正在使用和正确回滚中...此外,根据您的方案,放置您打开和提交事务的位置也很重要。你也应该在完成后关闭交易......
另外,你能详细说明发生异常的地方吗?听起来你正在保存一个父母,然后孩子正在投掷,因为父母的id为空?或者,它实际上是在拯救父母吗?
答案 1 :(得分:1)
配置log4net可能会有所帮助,以便您可以记录和查看NHibernate正在执行的操作......
我曾经遇到过使用Access的NHibernate的问题,并且能够通过设置日志记录来解决它,以便我可以准确找出问题的原因。
我收到的错误消息与您的错误消息不同,但this是我描述如何解决问题的文章。也许它对你有所帮助。 :)
答案 2 :(得分:0)
NHibernate开发人员非常劝阻身份。我们遇到的主要问题是,在您冲洗之前,您不会获得ID。在您的Int案例中,HiLo将是一个很好的替代品。
话虽如此,我认为你真的想要这样做......
<id name="Id" column="Id" unsaved-value="0">
<generator class="identity"/>
</id>
答案 3 :(得分:0)
我也遇到了这个错误,解决方法是将其包装在Ben提到的事务中。然而,我不能让Ben和gilles27代码工作 - 可能是因为我对泛型和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();
}
}
答案 4 :(得分:-2)
我认为不是生成器类=“身份”/&gt;
尝试generator class =“guid.comp”