0

NHibernate 的文档特别说

5.1.4.7。分配的标识符

如果您希望应用程序分配标识符(而不是让 NHibernate 生成它们),您可以使用分配的生成器。这个特殊的生成器将使用已经分配给对象的标识符属性的标识符值。使用此功能分配具有业务意义的键时要非常小心(几乎总是一个糟糕的设计决定)。

由于其固有的性质,使用此生成器的实体无法通过 ISession 的 SaveOrUpdate() 方法保存。相反,您必须通过调用 ISession 的 Save() 或 Update() 方法来显式指定 NHibernate 是否应该保存或更新对象。

但是我正在使用分配的标识符和 session.SaveOrUpdate() 并且我没有收到任何类型的错误/警告。

我错过了什么?他们是否改变了 SaveOrUpdate 的行为方式,现在它可以与分配的标识符一起使用?

我也在使用 Fluent NHibernate 的自动映射。

这是代码:

 public class MyIDConvention : IIdConvention
 {
      public void Apply(IIdentityInstance instance)
        {
            instance.GeneratedBy.Assigned();
        }
 }
 
 private static ISessionFactory CreateSessionFactory()
 {
      return Fluently.Configure().Database(SQLiteConfiguration.Standard.UsingFile("testDB.db"))
      .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Product>(cfg).Conventions.Add<MyIDConvention>()
      .BuildSessionFactory();
 }

当我这样做时,我期待一个错误:

 Product myProduct = new Product(presetID);
 session.SaveOrUpdate(myProduct);
 transaction.Commit();

但什么也没发生。

如果我遗漏了 myIDConvention,则会收到错误消息:NHibernate.StaleObjectStateException: Row is updated or deleted by another transaction(或未保存值映射不正确)。

谁能向我解释发生了什么事?

4

1 回答 1

-1

当使用分配的 id 时,NHibernate 可以通过将 id 与未保存的值设置进行比较来确定实体是否是持久的。我的理解是未保存的值设置允许使用 SaveOrUpdate 并且您引用的文档已过时/具有误导性。

例如,如果您的 id 是 int,则默认 unsaved-value 为 0。

5.1.4

unsaved-value(可选 - 默认为“合理”值):一个标识符属性值,指示实例是新实例化的(未保存),将其与在先前会话中保存或加载的瞬态实例区分开来。

于 2013-03-14T13:03:41.657 回答