我们在两个表,人员表和用户表之间分配了一个userobject。
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将首先将Name
插入Person
表,然后Username
和Password
插入User
表。
当插入User
- 表失败时(如尝试插入已使用用户名的用户),就会出现问题。事务失败,但不会回滚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();
}
我已将失败的会话in a gist中的日志文件放入。 User
实体在现实生活中稍微复杂一点,并且有一些认证内容正在进行,因此日志文件希望与绘制的图片1:1匹配...
答案 0 :(得分:3)
似乎解决了类似的问题here。回滚事务时,NHibernate不会还原会话中的更改,即如果在回滚后刷新会话,您将遇到所描述的问题。为了确保实体不会发生变化,当您回滚时,您还必须关闭会话。
答案 1 :(得分:0)
仅在Person对象中添加User对象并仅保存Person对象。在Mapping文件中使用Cascade.All()。或第二个选项是使用TransactionScope。
答案 2 :(得分:-1)
您可以在使用roleld支持事务后使用session.Clear(),而不是关闭会话,这将删除所有挂起的写入并使会话与新的一样好。 这对我的应用程序起了作用。