在我的 Spring-boot、Java 和 Thymeleaf 应用程序中,我有一个表单,使用新的客户端信息填写一次并保存到 SQL 数据库表中。当您想要编辑此客户端的信息并单击“保存”时,它最终会保存/更新信息,但也会删除名为 ResourceWebsiteAccess 的 SQL 子表中的信息。我无法判断它是否正在更新信息并且子表存在问题,或者它是否只是替换所有客户端信息并因此删除子表信息。有什么想法出了什么问题以及如何解决它吗?
以下是一些 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>
这是当您点击保存“按钮”时发生的 Controller 操作。
@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 的模型,它没有单独的 Controller ,但它在存储库上有它的
@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";
}
资源网站访问存储库:
@Transactional
public interface ResourceWebsiteAccessRepository extends CrudRepository<ResourceWebsiteAccess,Long>,JpaSpecificationExecutor {
ResourceWebsiteAccess findByClient(Client client);
}
最佳答案
您遇到的问题是您正在更新所有字段,包括表单中为空的字段。您真正想做的是仅更新那些已修改的值。为此,您可以在实体上使用 Hibernate 的 @DynamicUpdate
注释。
@Entity
@DynamicUpdate
@Table(name="Client")
@EntityListeners(AuditingEntityListener.class)
public class Client { ... }
您可以在下面的blog中阅读更多相关信息。 .
实现您想要做的事情的另一种方法是通过客户端的 id 获取客户端,然后使用您刚刚从表单收到的值设置新值。
@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;
}
关于java - 表单在更新当前客户端时,删除与父表连接的子表信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53163206/