简体   繁体   中英

Why doesn't my code update my entity object? Spring Hibernate MVC app

I have a Spring Hibernate MVC and trying to implement CRUD operations. I have gotten create, get, delete in a " RESTful " kinda way but I am having difficulties with update.

When trying to update the object, the parameter is /id?form, the controller code for that is:

@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";
    }

So, the JSP form for update gets filled with the object, using the id. The JSP update form is as follows:

<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>

Upon submit, the controller method that gets called should be:

@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/";
    }

I have tried the hibernate method update , saveOrUpdate , and merge invoiceServiceHibernate.updateInvoice(invoice) and it does not work.

The controller ends up creating a new invoice instead of updating the old one. Does anyone why that is the case? I was reading up on this link and it talks about using @ModelAttribute. I've tried it but it still does not work. Using @ModelAttribute or @Valid does nothing. The app does not create a new invoice but it does not update the current invoice.

Any suggestions?

Thanks!

You need a running transaction. Annotate updateInvoice with @Transactional .

If you don't have it set-up, check here . In short, you need <tx:annotation-driven /> in your spring config file, and to declare a transaction manager with a reference to your session/entity manager

Where's the ID in your JSP? It looks like you're not sending back invoice.id as part of your form.

Hibernate doesn't have any way to figure out which invoice it's supposed to update if the id isn't included somehow in the incoming request. The basic function of Spring's WebDataBinder isn't really as magic as it seems. All it does is make a new object (or use an existing one if it exists in the ModelMap) then string-match request parameters against bean setter names and call the setters. (There is of course some magic happening for type conversion and so forth.) If there's no ID in the request parameters, the ID field of your Entity will be blank when the WebDataBinder makes a new one. You need a way to provide the ID to the databinder.

There are two basic ways you can accomplish this.

First you can bind every field that's part of the Entity in your form. You'd have a hidden field for invoice.id, invoice.version, etc etc.

Second you can keep a copy of the Entity around in memory on the server. This of course introduces server side state, so isn't exactly RESTful. You could use Spring's @SessionAttributes on your controller to tell it to keep the Entity in memory and have the databinder update it with the new values, instead of creating a new one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM