0

I have tried to solve the problem since 3 days now, but I can´t. Actually I want to update a row, but instead of the update the .merge() makes a insert.

The Id is autogenerated from the mySql database.

This is the first button to call the formular, with the id from the prior persisted Report:

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

This is the aspect which should call the view 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";
}

Excerpt of view 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>

The last thing shoud be an merge(update) of the previus send object 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();
}

This is the object to update:

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

Can you please help me? Do you know why it performs an insert instead of update it?

Greetings

Loopek (:

3
  • Have you checked if the CRMReport's primary key field is set when updateReport is called? If that field is null, JPA will insert a new record instead of updating an existing one. Commented May 26, 2017 at 14:03
  • Spring MVC can only assemble your model from the data provided in the request, i.e. sent using the form. The id is therefore null. You can easily solve the problem by adding a hidden id input field to the form Commented May 26, 2017 at 14:07
  • Thank you for your Comment (: With a hidden input field with the id, the id is set. Before the merge the id is right but it was wrong anyway. The changes are now reworked in the question. Commented May 29, 2017 at 6:42

2 Answers 2

2

I think the problem might be related to this block:

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

First of all, for a hidden input field you won't show any validation error messages, so remove everything but the hidden input field itself.

Next, you are making an association between the input field and the id property of the newCRMReport object instance using the th:field="*{id}" attribute. But you are using also the th:value="${{reportId}} attribute, with a value (reportId) which I think is not available in the view model. That will end with a null or empty value in the id field.

Try replacing the previous block with the following one. Then check if the generated HTML is valid and the hidden field contains the id value.

<input type="hidden" th:field="*{id}" /> 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer (: I have removed the error message. Without the value field, the id is in the aspect "id before". But nonetheless at the command newCRMReport.merge() a new record is inserted.
0

Thank you all for your comments and answers. With your annotations I found out the answer.

I have now added the version, with the type:"hidden" to the update view.

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

The merge then performs an update.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.