0

在带有 Hibernate 4.1 的 Spring 3.1 MVC 应用程序中,我正在使用:

  • 声明式事务管理
  • 每个请求的会话
  • 通过在域对象中添加“版本”属性进行乐观锁定
  • 使用 saveOrUpdate() 重新附加分离的域对象

域对象在 GET 请求期间作为命令对象发送,以便用户更新。

为了不出现错误“乐观锁定失败;嵌套异常是 org.hibernate.StaleObjectStateException:行已被另一个事务更新或删除(或未保存的值映射不正确)”,我在每个 jsp 页面中都包含“ <form:hidden path="version"/>”并且更新工作正常。

为了进一步保护应用程序,我正在尝试向控制器添加以下内容:

@InitBinder
public void initBinder(WebDataBinder dataBinder, HttpServletRequest request) {
  if (request.getMethod().equals("POST")) {
   dataBinder.setDisallowedFields( new String[] {"version"});
  }
}

但是当我这样做时,我得到错误乐观锁定失败;嵌套异常是 org.hibernate.StaleObjectStateException:行已被另一个事务更新或删除(或未保存的值映射不正确)”。

有人可以解释一下我正在尝试做的事情作为一种方法是否有效以及我做错了什么?

我相信理想情况下,我应该尝试保护域对象的主键以及可能未被特定 jsp 页面修改的某些字段。

先感谢您。

4

1 回答 1

0

这看起来不正确,您不应该禁止绑定版本字段 - 如果您不允许绑定版本字段,那么您的命令对象将没有您最初从数据库中为对象检索的版本字段,并且在点持久化命令对象休眠将假定该行已被其他事务修改(因为数据库中的版本和命令对象不匹配)。

您可以尝试保护字段(id,版本)等,仅在第一次保存实体时(当 id 和 version 预计不存在时),但对于更新,必须存在原始 id 和版本.

于 2012-05-25T18:08:19.417 回答