1

我们在两个表之间拆分了一个用户对象,一个人表和一个用户表。

public UserMap() 
{
   Table("Person");
   Id(x => x.PersonId, "PersonId");
   Map(x => x.Name, "Name");

   Join("User", s => {
      s.Fetch.Join();
      s.KeyColumn("PersonId");
      s.Map(x => x.Username, "Username");
      s.Map(x => x.Password, "Password");
   });
}

在进行插入时,nHibernate 会先插入NamePerson表中,然后再Username插入PasswordUser表中。

当插入User-table 失败时会出现问题(例如尝试插入用户名已被占用的用户)。Person事务失败,但不会回滚到表中的插入。

    public User Save(User user)
    {
        var session = SessionHelper.GetCurrent();
        using (var dbTransaction = session.BeginTransaction())
        {
            try
            {
                session.SaveOrUpdate(user);
                dbTransaction.Commit();
            }
            catch (Exception)
            {

                dbTransaction.Rollback();
                throw;
            }                
        }

        return user;
    }

我们的 SessionFactory 也设置了 Fluent NHibernate

    public ISessionFactory BuildSessionFactory(string connectionString)
    {
        return Fluently.Configure().Database(OracleClientConfiguration.Oracle10.ConnectionString(c => c.Is(connectionString))
                                             .Provider<OracleDriverConnectionProvider>()
                                             .Driver<OracleDataClientDriver>()
                                             .ShowSql)
                                             .Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>())
                                             .BuildSessionFactory();
    }

我已将失败会话中的日志文件放在 gist中。实体在User现实生活中稍微复杂一些,并且正在进行一些身份验证,因此日志文件希望与绘制的图片 1:1 匹配...

4

3 回答 3

3

似乎在这里解决了类似的问题。当您回滚事务时,NHibernate 不会恢复您在会话中所做的更改,即如果您在回滚后刷新会话,您将遇到您描述的问题。为确保您的实体没有更改,当您回滚时,您还必须关闭会话。

于 2013-04-26T11:03:48.003 回答
0

仅在人员对象中添加用户对象并保存人员对象。在映射文件中使用 Cascade.All()。或第二个选项是使用 TransactionScope。

于 2013-04-26T11:56:18.640 回答
-1

您可以在角色返回事务后使用 session.Clear() 而不是关闭会话,这将删除所有挂起的写入并使会话与新会话一样好。这对我的应用程序起到了作用。

于 2015-01-28T14:42:41.437 回答