java - 为什么我的代码不更新我的实体对象? Spring Hibernate MVC 应用程序

标签 java hibernate spring jsp spring-mvc

我有一个 Spring Hibernate MVC 并尝试实现 CRUD 操作。我已经以“RESTful”的方式创建、获取、删除,但我在更新时遇到困难。

当尝试更新对象时,参数为/id?form,其 Controller 代码为:

@RequestMapping(value = "/{id}", params = "form", method = RequestMethod.GET)
    public String updateForm(@PathVariable("id") Long id, Model uiModel) {
        uiModel.addAttribute("invoice", invoiceServiceHibernate.getInvoice(id));
        return "invoices/update";
    }

因此,用于更新的 JSP 表单将使用 id 填充该对象。 JSP更新形式如下:

<c:if  test="${!empty invoice}">
<form:form method="PUT" commandName="invoice">
    <table>
        <tr>
            <td>Amount</td>
            <td><form:input value="${invoice.amount}" path="amount" /></td>
        </tr>
        ... more labels and fields ...
        <tr>
            <td colspan="3">
                <input type="submit" value="Update Invoice" />
            </td>
        </tr>
    </table>
</form:form>

提交后,被调用的 Controller 方法应该是:

@RequestMapping(method = RequestMethod.PUT)
    public String update(Invoice invoice, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
        if (bindingResult.hasErrors()) {
            uiModel.addAttribute("invoice", invoice);
            return "invoices/update";
        }
        uiModel.asMap().clear();
        invoiceServiceHibernate.updateInvoice(invoice);
        return "redirect:/invoices/";
    }

我尝试过 hibernate 方法 updatesaveOrUpdatemerge invoiceServiceHibernate.updateInvoice(invoice) 和这是行不通的。

Controller 最终创建一张新发票而不是更新旧发票。有人知道为什么会这样吗?我正在阅读this链接,它讨论了使用@ModelAttribute。我已经尝试过了,但仍然不起作用。使用 @ModelAttribute 或 @Valid 不会执行任何操作。该应用程序不会创建新发票,但不会更新当前发票。

有什么建议吗?

谢谢!

最佳答案

您的 JSP 中的 ID 在哪里?您似乎没有将发票.id 作为表单的一部分发回。

如果 id 未以某种方式包含在传入请求中,Hibernate 无法确定应更新哪个发票。 Spring的WebDataBinder的基本功能并不像看起来那么神奇。它所做的只是创建一个新对象(如果 ModelMap 中存在,则使用现有对象),然后根据 Bean setter 名称对请求参数进行字符串匹配并调用 setter。 (当然,类型转换等方面会发生一些神奇的事情。)如果请求参数中没有 ID,那么当 WebDataBinder 创建新的 ID 字段时,实体的 ID 字段将为空。您需要一种方法来向数据绑定(bind)器提供 ID。

有两种基本方法可以实现此目的。

首先,您可以绑定(bind)表单中实体的每个字段。您将有一个发票.id、发票.版本等的隐藏字段。

其次,您可以在服务器内存中保留实体的副本。这当然引入了服务器端状态,因此并不完全是 RESTful。您可以在 Controller 上使用 Spring 的 @SessionAttributes 来告诉它将实体保留在内存中,并让数据绑定(bind)器使用新值更新它,而不是创建一个新值。

关于java - 为什么我的代码不更新我的实体对象? Spring Hibernate MVC 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7906610/

相关文章:

java - 单击按钮时将焦点设置到 EditText

java - 如何使用 hibernate session ?

java - 属性 'driverClassName' 抛出异常;嵌套异常是 java.lang.IllegalStateException : Could not load JDBC driver class

java - 有没有办法在 Java Spring 中将不可预测数量的 Monos 合并到列表中?

java - 如果我们从数据库更改外键名称,它如何影响 hibernate ?

java - 添加额外的 java 文件到 playframework 类路径

java - java中两个组合框同步

java - Hibernate:使用 EntityManager 插入更新

java.lang.ClassNotFoundException : org. elasticsearch.http.AbstractHttpServerTransport

java - Hibernate 中的重复条目