java - 表单在更新当前客户端时,删除与父表连接的子表信息

标签 java sql hibernate spring-boot thymeleaf

在我的 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;
  ...    
}
我如何通过使用此 Controller 的表单将信息添加到子表中:

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

相关文章:

java - 如何使用 JPA Stream<GroupJson> 和整个数据库?

mysql - 如何从 MySQL 表创建一个 View 来计算每列中的特定条件?

mysql - 运算符在 vb.net 中用于组合框

java - REST Java 类 java.util.LinkedList 的消息正文编写器

java - java的db2连接问题

sql - 传递一个对象(.net 或 json 对象)作为 postgresql 函数的输入参数

spring - 基于 Maven 的项目使用 Spring Hibernate、EJB3.0、JPA JBOSS?

hibernate - Tomcat 7、Hibernate 3.6、PostgreSQL 9.2 | Maven java.lang.NoClassDefFoundError

java - btree算法的问题

java - Jackson JsonDeserializer 总是得到空值