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

nHibernate未插入guid id为的实体

  •  2
  • DanK  · 技术社区  · 15 年前

    我正在用流畅的NHibernate自动应用程序试验NHibernate(版本2.1.0.4000)。

    我的实体测试集使用默认整数ID保持良好状态

    我正在尝试对实体使用guid id id。不幸的是,将id属性更改为guid似乎会停止nhibernate插入对象。

    下面是实体类:

    public class User
    {
        public virtual int Id { get; private set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual string Email { get; set; }
        public virtual string Password { get; set; }
    
        public virtual List<UserGroup> Groups { get; set; }
    
    }
    

    下面是我使用的流畅的NHibernate配置:

            SessionFactory = Fluently.Configure()
                                //.Database(SQLiteConfiguration.Standard.InMemory)
                                .Database(MsSqlConfiguration.MsSql2008.ConnectionString(@"Data Source=.\SQLEXPRESS;Initial Catalog=NHibernateTest;Uid=NHibernateTest;Password=password").ShowSql())
                                .Mappings(m =>
                                    m.AutoMappings.Add(
                                        AutoMap.AssemblyOf<TestEntities.User>()
                                                .UseOverridesFromAssemblyOf<UserGroupMappingOverride>()))
                                .ExposeConfiguration(x =>
                                    {
                                        x.SetProperty("current_session_context_class","web");
                                    })
                                .ExposeConfiguration(Cfg => _configuration = Cfg)
                                .BuildSessionFactory();
    

    以下是使用整数ID时的日志输出:

    16:23:14.287 [4] DEBUG NHibernate.Event.Default.DefaultSaveOrUpdateEventListener - saving transient instance
    16:23:14.291 [4] DEBUG NHibernate.Event.Default.AbstractSaveEventListener - saving [TestEntities.User#<null>]
    16:23:14.299 [4] DEBUG NHibernate.Event.Default.AbstractSaveEventListener - executing insertions
    16:23:14.309 [4] DEBUG NHibernate.Event.Default.AbstractSaveEventListener - executing identity-insert immediately
    16:23:14.313 [4] DEBUG NHibernate.Persister.Entity.AbstractEntityPersister - Inserting entity: TestEntities.User (native id)
    16:23:14.321 [4] DEBUG NHibernate.AdoNet.AbstractBatcher - Opened new IDbCommand, open IDbCommands: 1
    16:23:14.321 [4] DEBUG NHibernate.AdoNet.AbstractBatcher - Building an IDbCommand object for the SqlString: INSERT INTO [User] (FirstName, LastName, Email, Password) VALUES (?, ?, ?, ?); select SCOPE_IDENTITY()
    16:23:14.322 [4] DEBUG NHibernate.Persister.Entity.AbstractEntityPersister - Dehydrating entity: [TestEntities.User#<null>]
    16:23:14.323 [4] DEBUG NHibernate.Type.StringType - binding null to parameter: 0
    16:23:14.323 [4] DEBUG NHibernate.Type.StringType - binding null to parameter: 1
    16:23:14.323 [4] DEBUG NHibernate.Type.StringType - binding 'ertr' to parameter: 2
    16:23:14.324 [4] DEBUG NHibernate.Type.StringType - binding 'tretret' to parameter: 3
    16:23:14.329 [4] DEBUG NHibernate.SQL - INSERT INTO [User] (FirstName, LastName, Email, Password) VALUES (@p0, @p1, @p2, @p3); select SCOPE_IDENTITY();@p0 = NULL, @p1 = NULL, @p2 = 'ertr', @p3 = 'tretret'
    

    以下是使用guid时的输出:

    16:50:14.008 [4] DEBUG NHibernate.Event.Default.DefaultSaveOrUpdateEventListener - saving transient instance
    16:50:14.012 [4] DEBUG NHibernate.Event.Default.AbstractSaveEventListener - generated identifier: d74e1bd3-1c01-46c8-996c-9d370115780d, using strategy: NHibernate.Id.GuidCombGenerator
    16:50:14.013 [4] DEBUG NHibernate.Event.Default.AbstractSaveEventListener - saving [TestEntities.User#d74e1bd3-1c01-46c8-996c-9d370115780d]
    

    这就是它无声失败的地方,没有异常抛出或进一步的日志条目。

    看起来它正在为新对象正确地生成guid id,但只不过比这更进一步。

    为了使用guid id,是否需要做一些不同的事情?

    谢谢,

    丹。

    2 回复  |  直到 15 年前
        1
  •  1
  •   Sean Carpenter    15 年前

    您应该检查您的应用程序(非映射)代码,并确保您正在提交NHibernate ITransaction 实例。

    当使用整数ID和 native identity generator,nhibernate必须立即插入一个新实例,以便生成ID值(即使事务尚未提交)。当使用类似于 guid.comb 这不依赖于数据库来生成ID,在提交封闭事务之前,nhibernate不会实际执行插入。

        2
  •  0
  •   Travis Heseman    15 年前

    我不完全确定自动映射的情况。

    但是,我可以告诉您的一件事是,确保在构造类的新实例时将其guid设置为guid.empty,而不是guid.new guid()。这向nHibernate发出信号,表示该对象是新的,应该插入而不是更新;对于int属性,这与零非常相似。nHibernate将在插入时将属性重新更新为生成的guid。

    public class Cat
    {
        public Cat()
            : base()
        {
            this.Id = Guid.Empty;
        }
    
        public virtual Guid Id { get; set; }
        ...
    }
    

    在手动映射情况下,映射如下所示:

    public class CatMap : ClassMap
    {
        public CatMap()
            : base()
        {
            this.Id(e => e.Id);
            ...
        }
    }