NHibernate提交db更改,无需显式调用以保存或更新

时间:2009-09-04 17:33:52

标签: nhibernate

我在ASP.NET中使用Nhibernate 2.0。 我在页面的开头启动事务并在最后提交事务。 在页面中: - 我得到一个物体 - 我改变了对象属性 - 我验证了对象 - 如果验证正常,我会在该对象上调用save-update - 如果验证错误,我不会在该对象上调用save-update - 我总是在页面末尾提交交易。

问题是,当验证错误并且我没有在对象上调用save-update时,提交transactin会在DB中提交更改。

我将FlushMode设置为Never但nothig change。

有什么建议吗?我错了什么?

3 个答案:

答案 0 :(得分:17)

  

在页面中: - 我得到一个对象

如果从会话中获取对象,那么您就会误解Update。更新用于将现有实体附加到会话。如果您从会话中获取实体,则该实体已附加到该会话,因此更新无意义。

在这种情况下SaveOrUpdate与Update无关 - 同样的事情。

NHibernate跟踪会话中对象的更改。当您提交事务或刷新会话时,它将检查是否有任何更改(有),然后将这些更改提交到数据库。这一点的重点在于,跟踪哪些对象被更改(脏)不是你的工作,它是NHibernates。

其他ORM可能要求您自己跟踪更改并在要更改的任何对象上明确调用某种更新,但NH不会以这种方式工作。

所以要回答你的问题,如果验证失败,你不想提交交易。

NH也对工作单元模式持主观态度。因此,如果您在验证工作的业务逻辑中对程序的不同逻辑部分进行提交,则可能会导致摩擦。

答案 1 :(得分:5)

我刚遇到同样的问题。 Eyston的回答非常有用,解释说无论你是否调用ISession.Update(object)或SaveOrUpdate(object),NH跟踪更改,提交事务都会提交更改。

有几种方法可以完成验证,以防止更改进入数据库。在单独的交易中进行所有验证和(可能的)保存。

using (ITransaction tx = session.BeginTransaction())
{
    // get your object
    // do your validation

    // if you pass validation:
    tx.Commit();

    // if not, roll it back
    tx.Rollback();
}

我解决了我的问题有点不同。如果我的验证失败,我不希望对该特定对象进行任何更新,因此我只是将其从会话中逐出。

if (!myObj.ValidateForSave())
{
    session.Evict(myObj);
}

这样做,您可以坚持单个事务,在页面开头处启动它,并在结束时提交它。如果您的对象验证失败,它将不在会话中,并且不会对数据库保留任何更改。

答案 2 :(得分:1)

在这种情况下适合我的解决方案是:

  1. 将Session FlushMode设置为'Commit'。

  2. 删除处理对象内存更新的代码中对“Flush”的所有引用。

  3. “保存”时,每个会话只能打开1个事务,然后丢弃该会话。