У меня есть два объекта, Contractor
, с полем ContractorData
, а у ContractorData
есть список объектов типа Invoice
:
Contractor
id
email
ContractorData
ContractorData
id
FistName
LastName
...
List<InvoiceData>
Для обновления Исполнителя у меня есть базовый контроллер
@GetMapping("/")
public String index(Model model, OAuth2Authentication authentication) {
String email = String.valueOf(((LinkedHashMap<String, Object>) authentication.getUserAuthentication().getDetails()).get("email"));
Contractor contractor = contractorRepository.findByEmail(email);
if (contractor == null) {
contractor = new Contractor();
contractor.setEmail(email);
contractorRepository.save(contractor);
}
model.addAttribute("contractor", contractor);
return "index";
}
и контроллер обновлений:
@RequestMapping(value = "/contractor/update/{id}", method = RequestMethod.POST, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String updateContractor(@PathVariable("id") String id, Contractor contractor, Model model) {
Contractor contractorPO = contractorRepository.findById(id).get();
ContractorData contractorData = ContractorData.builder()
.firstName(contractor.getContractorData().getFirstName())
.lastName(contractor.getContractorData().getLastName())
.businessName(contractor.getContractorData().getBusinessName())
.businessLocation(contractor.getContractorData().getBusinessLocation())
.nip(contractor.getContractorData().getNip())
.regon(contractor.getContractorData().getRegon())
.build();
contractorPO.setContractorData(contractorData);
contractorRepository.save(contractorPO);
model.addAttribute("contractor", contractorPO);
return "index";
}
Здесь все отлично работает.
Но тогда у меня есть контроллер, ведущий на страницу, на которой можно добавить InvoiceData
:
@RequestMapping(value = "/add/{id}")
public String addPage(@PathVariable("id") String id, Model model) {
InvoiceData invoiceData = new InvoiceData();
model.addAttribute("contractorid", id);
model.addAttribute("invoicedata", invoiceData);
return "add";
}
И контроллер для добавления счета:
@RequestMapping(value = "/addinvoice/{id}", method = RequestMethod.POST, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String addInvoice(@PathVariable("id") String id, InvoiceData data, Model model) {
Contractor contractor = contractorRepository.findById(id).get();
contractor.getInvoices().add(data);
contractorRepository.save(contractor);
model.addAttribute("contractor", contractor);
return "index";
}
На стороне HTML-формы форма index.html выглядит следующим образом:
<form action="#" th:action="@{/contractor/update/{id}(id=${contractor.id})}" th:object="${contractor}" method="post">
<ul class="form-style-1">
<li>
<label>First Name<span class="required">*</span></label>
<input type="text" th:field="*{contractorData.firstName}" id="firstName" th:value="${contractor.contractorData?.firstName}">
</li>
<li>
<label>Last Name<span class="required">*</span></label>
<input type="text" th:field="*{contractorData.lastName}" id="lastName" th:value="${contractor.contractorData?.lastName}">
</li>
... and more
<li>
<input type="submit" value="Submit" />
</li>
</ul>
</form>
Форма для add.html
выглядит так же, она отличается от объекта:
<form action="#" th:action="@{addinvoice/{id}(id=${contractorid})}" th:object="${invoicedata}" method="post">
<ul class="form-style-1">
<li>
<label>Reception date<span class="required">*</span></label>
<input type="date" th:field="*{receptionDate}" id="receptionDate">
</li>
... and more
<li>
<input type="submit" value="Submit" />
</li>
</ul>
</form>
Проблема с сохранением InvoiceData
. Когда я заполняю форму и нажимаю Отправить - я получаю сообщение об ошибке:
Произошла непредвиденная ошибка (тип = неверный запрос, статус = 400).
Проверка не удалась для object = 'invoiceData'. Количество ошибок: 4
ВАЖНОЕ РЕДАКТИРОВАНИЕ
На выходе консоли я также получаю сообщение об ошибке:
Field error in object 'invoiceData' on field 'contractDate': rejected value [2019-04-11]; codes [typeMismatch.invoiceData.contractDate,typeMismatch.contractDate,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [invoiceData.contractDate,contractDate]; arguments []; default message [contractDate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'contractDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2019-04-11'; nested exception is java.lang.IllegalArgumentException]
Но, как я уже говорил, ВСЕ прекрасно работает с ContractorData
формой обновления ...