В моем приложении 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>
Это действие контроллера, которое происходит при нажатии кнопки «Сохранить».
@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"))
client.setOnboardedDate(LocalDate.now());
else if (!client.getStatus().equals("active"))
client.setOnboardedDate(null);
try{
client=clientRepository.save(client);
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;
}
Клиентский репозиторий:
@Transactional
public interface ClientRepository extends CrudRepository<Client,Long>, JpaSpecificationExecutor {
Client save(Client entity);
List<Client> findByPrincipleNameContaining(String principleName);
List<Client> findByNdaSent(Boolean ndaSent);
List<Client> findByLegalNameContaining(String legalName);
List<Client> findByYearsExperienceContaining(String yearsExperience);
List<Client> findByLicenses(String licenses);
Client findById(Long id);
void delete(Client entity);
List<Client> findAll();
@Query("SELECT c FROM Client c Where c.status = 'active' AND ((c.contractExecuted=false OR c.agencyLicenseReceived=false OR c.eoReceived=false OR c.w9 =false OR c.directDepositCommissionAgreement=false) OR c.licenses!='Accident & Health' AND (c.producerAppointmentForm=false OR c.prepaymentAuthorizationAms360=false))")
List<Client> findClientsMissingDocs();
List<Client> findByNdaSentAndNdaSentDateBetween(Boolean ndaSent,LocalDate start,LocalDate end);
List<Client> findByContractSubmittedAndContractSubmittedDateBetween(boolean b, LocalDate startOfMonth, LocalDate now);
List<Client> findByStatus(String prospect);
}
Вот некоторые из client.java, модель для формы.
@Entity
@Table(name="Client")
@EntityListeners(AuditingEntityListener.class)
public class Client {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ClientId")
private Long id;
...
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
@JoinColumn(name = "client")
private List<Employee> employees= new ArrayList<>();
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
@JoinColumn(name = "client")
private List<VendorService> vendorServices=new ArrayList<>();
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
@JoinColumn(name="client")
private List<ResourceWebsiteAccess> resourceWebsiteAccess=new ArrayList<>();
public List<ResourceWebsiteAccess> getResourceWebsiteAccess() {
return resourceWebsiteAccess;
}
public void setResourceWebsiteAccess(List<ResourceWebsiteAccess> resourceWebsiteAccess) {
this.resourceWebsiteAccess = resourceWebsiteAccess;
}
}
Вот модель ResourceWebsiteAccess, у нее нет отдельного контроллера, но он есть в репозитории
@Entity
@Table(name = "ResourceWebsiteAccess")
public class ResourceWebsiteAccess {
@Override
public String toString() {
return micrositeLink;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ResourceWebsiteAccessId")
private Long id;
private String micrositeLink;
private String partnerPortalLink;
@OneToOne
@JoinColumn(name = "client")
private Client client;
...
}
Как я добавляю информацию в дочернюю таблицу через форму, которая использует этот контроллер:
@RequestMapping(value="/settings/client/{id}")
public String links(@PathVariable("id")Client client, Model model){
ResourceWebsiteAccess access= accessRepository.findByClient(client);
if (access==null)
access= new ResourceWebsiteAccess();
model.addAttribute("client",client);
model.addAttribute("newUser",new ResourceWebsiteUser());
model.addAttribute("users",repository.findByClient(client));
model.addAttribute("access",access);
return "settings";
}
ResourceWebsiteAccess Repository:
@Transactional
public interface ResourceWebsiteAccessRepository extends CrudRepository<ResourceWebsiteAccess,Long>,JpaSpecificationExecutor {
ResourceWebsiteAccess findByClient(Client client);
}