Почему мой код не обновляет мой объект? Приложение Spring Hibernate MVC - PullRequest
0 голосов
/ 26 октября 2011

У меня есть Spring Hibernate MVC и я пытаюсь реализовать CRUD операции. Я получил "создать, получить, удалить" в некотором роде, но у меня возникли проблемы с обновлением.

При попытке обновить объект, параметр / id? Form, код контроллера для этого:

@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 для обновления заполняется объектом, используя идентификатор. Форма обновления 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>

После отправки вызываемый метод контроллера должен быть:

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

Я пробовал спящий метод update, saveOrUpdate и merge invoiceServiceHibernate.updateInvoice(invoice), и он не работает.

Контроллер в конечном итоге создает новый счет, а не обновляет старый. Кто-нибудь, почему это так? Я читал по этой ссылке, и она говорит об использовании @ModelAttribute. Я пробовал это, но это все еще не работает. Использование @ModelAttribute или @Valid ничего не дает. Приложение не создает новый счет-фактуру, но не обновляет текущий счет-фактуру.

Есть предложения?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 26 октября 2011

Где идентификатор в вашем JSP? Похоже, вы не отправляете invoice.id как часть вашей формы.

Hibernate не имеет никакого способа выяснить, какой счет он должен обновить, если идентификатор не включен каким-либо образом во входящий запрос. Основная функция Spring WebDataBinder не так волшебна, как кажется. Все, что он делает - это создает новый объект (или использует существующий, если он существует в ModelMap), затем сопоставляет параметры запроса строки с именами установщика бинов и вызывает установщики. (Конечно, происходит какое-то волшебство для преобразования типов и т. Д.) Если в параметрах запроса нет идентификатора, поле идентификатора вашей сущности будет пустым, когда WebDataBinder создаст новую. Вам нужен способ предоставить идентификатор для базы данных.

Есть два основных способа сделать это.

Сначала вы можете связать каждое поле, которое является частью сущности в вашей форме. У вас будет скрытое поле для invoice.id, invoice.version и т. Д. И т. Д.

Во-вторых, вы можете хранить копию сущности в памяти на сервере. Это, конечно, вводит состояние на стороне сервера, поэтому не совсем RESTful. Вы могли бы использовать @SessionAttributes Spring на своем контроллере, чтобы сказать ему, чтобы он сохранял сущность в памяти и обновлял базу данных, обновляя ее новыми значениями, вместо создания новых.

2 голосов
/ 26 октября 2011

Вам нужна текущая транзакция. Аннотировать updateInvoice с @Transactional.

Если у вас его нет, отметьте здесь . Короче говоря, вам нужно <tx:annotation-driven /> в вашем весеннем конфигурационном файле и объявить менеджер транзакций со ссылкой на ваш менеджер сессий / сущностей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...