Java 为什么';我的代码不能更新我的实体对象吗?Spring Hibernate MVC应用程序
我有一个Spring Hibernate MVC,试图实现Java 为什么';我的代码不能更新我的实体对象吗?Spring Hibernate MVC应用程序,java,hibernate,spring,jsp,spring-mvc,Java,Hibernate,Spring,Jsp,Spring Mvc,我有一个Spring Hibernate MVC,试图实现CRUD操作。我已经以“RESTful”的方式创建、获取和删除了,但我在更新方面遇到了困难 尝试更新对象时,参数为/id?form,其控制器代码为: @RequestMapping(value = "/{id}", params = "form", method = RequestMethod.GET) public String updateForm(@PathVariable("id") Long id, Model uiMo
CRUD
操作。我已经以“RESTful
”的方式创建、获取和删除了,但我在更新方面遇到了困难
尝试更新对象时,参数为/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表单使用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>
我尝试了hibernate方法update
,saveOrUpdate
,和merge
invoiceServiceHibernate.updateInvoice(invoice)
,但它不起作用
控制器最终创建新发票,而不是更新旧发票。有人知道为什么会这样吗?我正在阅读link,它谈到了如何使用@modeldattribute。我试过了,但还是不行。使用@modeldattribute或@Valid不起任何作用。应用程序不会创建新发票,但不会更新当前发票
有什么建议吗
谢谢 您需要一个正在运行的事务。用
@Transactional
注释updateInvoice
如果您没有设置它。简而言之,在spring配置文件中需要
,并且要声明一个引用会话/实体管理器的事务管理器,需要一个正在运行的事务。用@Transactional
注释updateInvoice
如果您没有设置它。简而言之,您需要在spring配置文件中声明一个事务管理器,并引用您的会话/实体管理器,JSP中的ID在哪里?看起来您没有将invoice.id作为表单的一部分发回 如果传入请求中没有包含id,Hibernate无法确定应该更新哪个发票。Spring的WebDataBinder的基本功能并不像看上去那么神奇。它所做的只是创建一个新对象(或者使用一个现有对象,如果它存在于ModelMap中),然后根据bean setter名称字符串匹配请求参数并调用setter。(类型转换等方面当然有一些神奇的事情发生。)如果请求参数中没有ID,那么当WebDataBinder创建新的ID字段时,实体的ID字段将为空。您需要一种向databinder提供ID的方法 有两种基本方法可以实现这一点 首先,可以绑定表单中实体的每个字段。您将有一个invoice.id、invoice.version等的隐藏字段
其次,您可以在服务器的内存中保留实体的副本。这当然引入了服务器端状态,因此并不完全是RESTful。您可以在控制器上使用Spring的@SessionAttributes命令它将实体保存在内存中,并让databinder使用新值更新它,而不是创建新值。JSP中的ID在哪里?看起来您没有将invoice.id作为表单的一部分发回 如果传入请求中没有包含id,Hibernate无法确定应该更新哪个发票。Spring的WebDataBinder的基本功能并不像看上去那么神奇。它所做的只是创建一个新对象(或者使用一个现有对象,如果它存在于ModelMap中),然后根据bean setter名称字符串匹配请求参数并调用setter。(类型转换等方面当然有一些神奇的事情发生。)如果请求参数中没有ID,那么当WebDataBinder创建新的ID字段时,实体的ID字段将为空。您需要一种向databinder提供ID的方法 有两种基本方法可以实现这一点 首先,可以绑定表单中实体的每个字段。您将有一个invoice.id、invoice.version等的隐藏字段
其次,您可以在服务器的内存中保留实体的副本。这当然引入了服务器端状态,因此并不完全是RESTful。您可以在控制器上使用Spring的@SessionAttributes命令它将实体保留在内存中,并让databinder使用新值更新实体,而不是创建新值。谢谢,我在InvoiceDAO类下有它。我有@Transactional用于创建、删除和获取。以及其他设置?您确定有正在运行的事务吗?放一个断点,看看跟踪中是否有
TransactionInterceptor
。我会调查TransactionInterceptor的事情。实际上,我有一个InvoiceDAO和另一个InvoiceService类。@Transactional位于InvoiceService类上。如果我尝试将@Transactional添加到InvoiceDAO,它会给我bean错误。InvoiceDAO updateInvoice方法调用sessionFactory.getCurrentSession().merge(发票),InvoiceService.updateInvoice方法调用InvoiceDAO.updateInvoice(发票)。我在InvoiceServiceHibernate类的updateInvoice下放置了一个断点,并在调试模式下启动服务器。调用了该方法,但该发票的id为null。不知何故,从我将更新表单提交给控制器时起,用于填充该表单的“id”就消失了。我该怎么做呢?将其放入url并使用@PathVariable={id}?谢谢,是的,你应该有一个隐藏的字段来保存InvoiceThank的id,我在InvoiceDAO类下有它。我有@Transactional用于创建、删除和获取。以及其他设置?您确定有正在运行的事务吗?放一个断点,看看跟踪中是否有TransactionInterceptor
。我会调查TransactionInterceptor的事情。实际上,我有一个InvoiceDAO和另一个InvoiceService类。@Transactional位于InvoiceService类上。如果我尝试将@Transactional添加到InvoiceDAO,它会给我bean错误。InvoiceDAO updateInvoice方法调用sessionFactory.getCurrentSession().merge(在
@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/";
}