JPA Hibernate 使用合并进行插入而不是更新

JPA Hibernate makes a insert instead of an update with merge

从 3 天以来,我一直在尝试解决这个问题,但我做不到。 实际上我想更新一行,但是 .merge() 不是更新而是插入。

ID 是从 mySql 数据库自动生成的。

这是调用公式的第一个按钮,其 ID 来自之前保留的报告:

<a th:href="@{|/reports/updateForm/${reportId}|}">
<button class="button btn-default btn-xs pull-right" type="button" th:title="#{report.formEdit}">
<i class="fa fa-edit fa-fw"></i></button></a>

这是应该调用视图 updateformular 的方面:

@RequestMapping(value = "/updateForm/{id}", produces = "text/html", method = RequestMethod.GET)
public String ReportController.updateForm(@PathVariable("id") long id, Model model) {

    CRMReport newCRMReport = CRMReport.findCRMReport(id);
    model.addAttribute("newCRMReport", newCRMReport);

    return "reports/update";
}

视图更新摘录:

<form action="#" class="form" role="form"
th:object="${newCRMReport}" th:action="@{/reports/update/}"
th:method="put">

<div class="modal-body col-lg-6 form-left">

<div class="panel panel-info">
<div class="panel-heading">
    <i th:text="#{report.info}"></i>
    </div>
</div>

//Example of the send data fields
<div class="form-group" th:classappend="${#fields.hasErrors('projectState')} ? error">
<label for="projectState" th:text="#{report.projectstatus}"></label> 
<select class="form-control" id="projectState" th:field="*{projectState}"
        th:size="${pros.length}" multiple="multiple">
<option th:each="pro : ${pros}" th:value="${{pro}}" th:field="*{projectState}" th:text="${pro}"></option>
    </select>
</div>

<div class="form-group">
<div>
<input type="hidden" th:field="*{id}" class="form-control" id="id"/>
</div>
</div>

<div class="modal-footer col-lg-12">
<button name="action" value="cancel" type="submit"
        class="btn btn-default pull-right">
<i class="fa fa-times fa-fw"></i> 
<i th:text="' '+#{report.cancel}"></i>
        </button>

<button name="action" value="save" type="submit"
    class="btn btn-primary pull-right">
<i class="fa fa-save fa-fw"></i> 
<i th:text="' '+#{report.show}"></i>
        </button>
        </div>

最后一件事应该是合并(更新)之前发送的对象 newCRMReport:

@RequestMapping(value = "/update", produces = "text/html", method = RequestMethod.PUT, params = "action=save")
public String ReportController.updateReport(@Valid @ModelAttribute("newCRMReport") CRMReport newCRMReport,
        BindingResult result, Model model, SessionStatus status) {      

        // ID will be x, from the prior object 
        System.out.println("id before: " + newCRMReport.getId());   

        status.setComplete();
        newCRMReport = newCRMReport.merge();

        // ID will be x+1, from the new object 
        System.out.println("id then: " + newCRMReport.getId());
        return "redirect:/reports/list/" + newCRMReport.getId();
}

这是要更新的对象:

@RooJavaBean
@RooToString
@RooJpaActiveRecord(table = "crm_report")
public class CRMReport{

    private String projectState;

    private String sector;

    private String location;

    private String client;

    private String company;

    @JoinColumn
    @ManyToOne
    private CRMUser responsible;

    private String relevance;

    private String volumeFrom;

    private String volumeTo;

    private String chance;

    @Temporal(TemporalType.TIMESTAMP)
    @DateTimeFormat(pattern = "dd.MM.yyyy HH:mm:ss")
    private Date dateFrom;

    @Temporal(TemporalType.TIMESTAMP)
    @DateTimeFormat(pattern = "dd.MM.yyyy HH:mm:ss")
    private Date dateTo;

    private String timeSpanFrom;

    private String timeSpanTo;

    @JoinColumn
    @ManyToOne
    private CRMUser createdBy;

    @Temporal(TemporalType.TIMESTAMP)
    @DateTimeFormat(style = "M-")
    private Date createdAt;
}    

你能帮帮我吗?你知道为什么它执行插入而不是更新吗?

问候

路佩克 (:

我认为问题可能与此块有关:

<div class="form-group">
<div>
<input type="hidden" th:field="*{id}" class="form-control" id="id" th:value="${{reportId}}"/> 
<span class="help-inline" th:errors="*{id}">[error]</span>
</div>
</div>

首先,对于隐藏的输入字段,您不会显示任何验证错误消息,因此请删除隐藏输入字段本身以外的所有内容。

接下来,您要在输入字段和 newCRMReport 对象实例的 id 属性 之间建立关联,使用th:field="*{id}" 属性。但是您还使用了 th:value="${{reportId}} 属性,其值 (reportId) 我认为不是在视图模型中可用。这将在 id 字段中以 null 或空值结尾。

尝试用下一个替换上一个块。然后检查生成的HTML是否有效,隐藏字段是否包含id值

<input type="hidden" th:field="*{id}" /> 

感谢大家的评论和回答。通过您的注释,我找到了答案。

我现在已经将版本添加到更新视图中,类型为:"hidden"。

               <div class="form-group">
                <div>
                    <input type="hidden" th:field="*{version}"
                   class="form-control" id="version"/>
                   </div>
                </div>

合并然后执行更新。