休眠。如何将对象与数据库值相关联?

时间:2013-08-13 15:05:37

标签: java spring hibernate java-ee

我有:

class Candidate {

    private String name;
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "candidate_vacancy", joinColumns = @JoinColumn(name = "candidate_id"), inverseJoinColumns = @JoinColumn(name = "vacancy_id"))
    List<Vacancy> list;
//get and set methods
}

以html格式写道:

<form action="saveCandidate">
  name: <input type="text" value="${candidate.name}" name="name" />
type="submit" value="save changes" />

在@Controller中我写了这段代码:

@RequestMapping("/saveCandidate")
    public String saveCandidate(Model model, @ModelAttribute Candidate candidate) {
        candidateService.update(candidate);
        return "candidateMenu";
    }

但是,如果我更新候选对象,数据库中的适当空位将变为空。

我想我可以手动从db填充空缺,将其附加到候选人并更新,但我认为是更正确的方式!

3 个答案:

答案 0 :(得分:0)

从我的观点来看,CandidateVacancy之间不应该有任何直接关系。据我了解,该关系更多地基于查询,或者更多地基于查询上应用的某些业务规则。

所以我在我的服务/ DAO中使用List<Vacancy> getVacancies(Candidate candidate)方法而不是数据库关系。实现该方法时,调用Hibernate来执行所需的查询,并在需要时应用任何业务规则。您将始终拥有指定用户的更新空缺列表。

否则,正如您已经看到的,无论何时添加新的CandidateVacancy,您都需要手动添加两者之间的关系。这与Hibernate无关,而是与关系数据库的工作方式有关。

答案 1 :(得分:0)

由于以下原因,您无法在此情况下将域对象用作绑定目标:

  1. 您需要获取现有对象的所有关系(或者它们将在您的情况下被删除)
  2. 这可能是一个安全问题。我可以在浏览器中更改您的表单,添加一些输入字段并更新数据库中的其他字段。
  3. 你可以使用特殊的DTO对象(比如你的html表单字段对应的CandidateForm):

    <form action="saveCandidate">
      <input type="hidden" value="${candidate.id}" name="id" />
      name: <input type="text" value="${candidate.name}" name="name" />
    
    @RequestMapping("/saveCandidate")
    public String saveCandidate(Model model, @ModelAttribute CandidateForm candidateForm) {
        Candidate candidate = new Candidate();
        if(candidateForm.getId() != null) {
           candidate = candidateService.getById(candidateForm.getId());
           // load existed object with relations, so they will be not removed
        }
        copyFieldsFromDtoToDomainObject(candidateForm, candidate);
        candidateService.update(candidate); // I supose that this is actually saveOrUpdate
        return "candidateMenu";
    }
    

    id是主键。

答案 2 :(得分:0)

您可以使用位于JavaBean中的特殊方法更新对象:

class Candidate {

    private String name;
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "candidate_vacancy", joinColumns = @JoinColumn(name = "candidate_id"), inverseJoinColumns = @JoinColumn(name = "vacancy_id"))
    List<Vacancy> list;
    //get and set methods

    public Candidate updatePublicInfo(Candidate newCandidate) {
        this.name = newCandidate.getName();
        return this;
    }
}

比在你的服务中做:

class CandidateServiceImpl implements CandidateService {

    // other methods

    public void update(Candidate candidate) {
        Candidate oldCandidate = candidateDao.findById(candidate.getId());
        oldCandidate.updatePublicInfo(candidate);
        candidateDao.save(oldCandidate);
    }
}