Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么';我的代码不能更新我的实体对象吗?Spring Hibernate MVC应用程序_Java_Hibernate_Spring_Jsp_Spring Mvc - Fatal编程技术网

Java 为什么';我的代码不能更新我的实体对象吗?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

我有一个Spring Hibernate MVC,试图实现
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/";
    }