В моем приложении Spring-boot, Java и Thymeleaf у меня есть форма, которая заполняется один раз новой информацией о клиенте и сохраняется в таблице базы данных SQL. Когда вы хотите отредактировать информацию этого клиента и нажмите «Сохранить», оно завершает сохранение / обновление информации, а также удаление информации в дочерней таблице SQL, называемой ResourceWebsiteAccess. Я не могу сказать, обновляет ли он информацию, и есть проблема с дочерней таблицей, или если она просто заменяет всю информацию о клиентах и, следовательно, удаляет информацию дочерней таблицы. Любые идеи, что происходит не так, и как это сделать?
Вот некоторые из html-форм:
<form enctype="multipart/form-data" th:action="${clientEndpoint}" method="post" th:object="${client}" class="tab-content"> <div class="tab-pane" id="prospect-profile"> <div th:replace="prospectProfile :: prospect-profile"></div> </div> <div class="tab-pane" id="affiliates"> <div class="row"> <h4>Affiliate Competency</h4> <br/> <div th:replace="affiliates/personalLines :: personal-lines"></div> </div> <hr/> <div class="row"> <div th:replace="affiliates/commercialLines :: commercial-lines"></div> </div> <hr/> </div> <input id="submitButton" type="submit" value="Save" name="save" class="btn btn-success finish" data-loading-text="Saved!" disabled="true"/><br/> </form>
Всего 3 ответа
Проблема, с которой вы сталкиваетесь, заключается в том, что вы обновляете все поля, в том числе те, которые поступают как нулевые из вашей формы. То, что вы действительно хотите сделать, - это обновление только тех значений, которые были изменены. Для этого вы можете использовать аннотацию @DynamicUpdate
Hibernate для вашей сущности.
@Entity
@DynamicUpdate
@Table(name="Client")
@EntityListeners(AuditingEntityListener.class)
public class Client { ... }
Подробнее об этом читайте в следующем блоге .
Другой способ добиться того, что вы пытаетесь сделать, - это получить клиент по его идентификатору, а затем установить новые значения с теми, которые вы только что получили из своей формы.
@RequestMapping(value="/saveClient")
@ResponseBody
public JSONObject saveClient(Model model,
@ModelAttribute(value="client") Client client) {
Boolean saved=false;
JSONObject response=new JSONObject();
Client clientBeforeUpdate=clientRepository.findById(client.getId());
if (clientBeforeUpdate!=null && !clientBeforeUpdate.getStatus().equals("active") && client.getStatus().equals("active"))
clientBeforeUpdate.setOnboardedDate(LocalDate.now());
else if (!client.getStatus().equals("active"))
clientBeforeUpdate.setOnboardedDate(null);
try{
// Set the rest of the needed changes from your new client.
clientBeforeUpdate=clientRepository.save(clientBeforeUpdate);
saved=true;
response.put("clientId",client.getId());
}catch (DataAccessException e) {
e.printStackTrace();
response.put("error",e.getLocalizedMessage());
response.put("cause",e.getLocalizedMessage());
}
response.put("success",saved);
return response;
}
Поскольку вы сохраняли ResourceWebsiteAccess, добавьте добавочное и обновляемое значение false в @JoinColumn
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
@JoinColumn(name="client",insertable=false,updatable=false)
private List<ResourceWebsiteAccess> resourceWebsiteAccess=new ArrayList<>();
Я закончил добавление @DynamicUpdate к модели, удалив OrphanRemoval = true; в модели и добавление client.setResourceWebsiteAccess (clientBeforeUpdate.getResourceWebsiteAccess ()), к контроллеру. Эти три шага исправили мою проблему, и теперь все отображается. Благодаря @AlianCruz