【问题标题】:Spring MVC Hibernate save Java Object between response and requestSpring MVC Hibernate 在响应和请求之间保存 Java 对象
【发布时间】:2016-10-04 17:54:32
【问题描述】:

我正在详细解释我的申请中的申请流程。我正在开发一个数据库查看器应用程序。用户可以使用此应用程序查看我的数据库中的所有记录(行),并且可以从 UI 进行编辑。此应用程序运行良好。现在我想实现乐观锁定,因为我在 DB 中创建了一个版本字段。现在我遇到了一个设计问题,

直到现在在我的应用程序中,当用户查看记录并想要编辑它时,在我的控制器方法中,我正在执行 Hibernate 加载并在编辑 JSP 页面中显示结果。现在,当用户在页面上单击“保存”时,我必须保存记录。因为它是一个非常复杂的实体,所以我正在从 DB 中重新填充这个实体并进行更改并进行 Hibernate 保存或更新。

现在,我想实现版本控制,因此我不想在保存或更新之前重新填充实体。不知何故,我想保持我复杂实体的安全,并在我想更新时使用它。在我的情况下,JSP 隐藏表单字段是不可能的。在用户单击“保存”按钮并使用它保存在数据库中之前,我在哪里可以保证我的实体安全?什么是可能的和最好的方法。

更新:

我已经查看了互联网上的各种帖子,并计划实现 EHcache 框架。

【问题讨论】:

  • 会议将是一个显而易见的地方。 docs.oracle.com/javaee/5/api/javax/servlet/http/…
  • @AlanHay 但不知何故,现在当我这样做时 (session.getAttribute("obj")).equals(DAO.get(...)) 不匹配。我越来越假了。我已经在对象的所有成员变量上验证了 eqauls 方法。他们应该是平等的吧?

标签: java hibernate spring-mvc versioning spring-form


【解决方案1】:

你有两个选择:

将状态存储在服务器(在会话中)或客户端(在隐藏的表单字段中)。您可以使用 HMAC 保护客户端数据,但这需要处理时间。为方便起见,我建议使用服务器端会话

我在这里的回答包括一个如何使用带有乐观锁定的会话的示例:Spring MVC: Validation, Post-Redirect-Get, Partial Updates, Optimistic Concurrency, Field Security

【讨论】:

  • 除了使用会话之外还有其他选择吗?我坚持的原因是,我们不想让服务器负担过重(我们想停止更多会话的内存消耗)。有没有办法使用 Hibernate 缓存或第三方协助来缓存对象?
  • @EagleRider 您可以将状态存储在浏览器的隐藏表单字段中
  • 我们的对象非常复杂。近两百场。所以寻找替代品。谢谢你的帮助。
  • @EagleRider 1. 如果操作数据库中的表有 200 个字段,那么您做错了。 2. 我说你有两个选择,列出来。选择一个或另一个。使用更多内存(会话)或更多带宽/处理器(客户端)。 3. 这些天 RAM 是 $30/8GB
  • 是的。如果我们没有找到任何替代方案,我们最终可能会使用隐藏的 id,形式中的版本号。但我们仍在构建应用程序,因此试图收集所有可能的解决方案。感谢您的耐心等待,您的意见很有帮助。 :) 谢谢。
【解决方案2】:

这就是@SessionAttributes 的用途。无论您需要如何将对象存储在某处,您都可以尝试弄乱并找出自己的解决方案或使用默认解决方案。

@SessionAttributes("your-model")
@Controller
public class YourController {

    @RequestMapping(method = GET)
    public String show(long id, Model model) {
        // Get your entity
        model.addAttribute("your-model", entity);
        return "edit";
    }

    @RequestMapping(method = POST) {
    public String show(@Valid @ModelAttribute("your-model") YourModel model, SessionStatus status) {
        // Save your entity
        status.setComplete();
        return "list";
    }
}

无论您的实现方式如何,您仍然需要将数据(部分)保存在内存中。如前所述,您可以尝试在自己的解决方案中破解,或使用默认的弹簧机制。

像 EhCache 这样的解决方案仍然在内存中缓存内容,如果需要,可以卸载到其他存储。您可以为会话配置相同的内容(取决于您的容器)。或者使用Spring Session 之类的东西来获得不同的选项。

无论如何,我会先将它存储在会话中,然后开始测量,如果它真的成为问题,请找出另一种在请求之间存储实体的方法。但是从简单开始,衡量然后改进,而不是试图解决可能发生的问题。

【讨论】:

  • @m-deinum 在我的情况下使用会话的问题是分布式生产环境。他们不能保证每个请求都会发送到同一个服务器。在这种情况下如何使用会话。
  • 如前所述,您可以使用 Spring Session(链接包含在答案中)。
猜你喜欢
  • 1970-01-01
  • 2011-06-08
  • 2011-08-07
  • 1970-01-01
  • 1970-01-01
  • 2021-04-07
  • 2021-02-22
  • 1970-01-01
  • 2015-03-11
相关资源
最近更新 更多