我有这个模型和hibernate映射:
@Entity
@Table(name = "candidate")
public class Candidate extends Person {
private Set<Vacancy> vacancies= new HashSet<Vacancy>();
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "candidate_vacancy", joinColumns = @JoinColumn(name = "candidate_id"), inverseJoinColumns = @JoinColumn(name = "vacancy_id"))
public Set<Vacancy> getVacancies() {
return vacancies;
}
public void setVacancies(Set<Vacancy> vacancies) {
this.vacancies = vacancies;
}
}
人员类:
@MappedSuperclass
public abstract class Person {
private Integer id;
private String name;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY )
@Column (name = "id")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "name")
@NotEmpty
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
空缺映射
@Entity
@Table(name = "vacancy")
@XmlRootElement(name="vacancy")
public class Vacancy {
...
@ManyToMany(mappedBy = "vacancies", fetch = FetchType.EAGER)
public Set<Candidate> getCandidates() {
return candidates;
...
}
}
我有这么高的形式:
<form action="saveCandidate" method="POST">
name: <input type="text" value="${candidate.name}" name="name" />
<input type="hidden" name="id" value="${candidate.id}">
<input type="submit" value="save changes" />
</form>
我在@controller方法中处理我的表单:
public String saveCandidate(Model model, @ModelAttribute Candidate candidate) {
candidateService.update(candidate);
return "candidateMenu";
}
用这种方式,我有问题。从我的数据库中删除与candodate相关的职位空缺。我解决了这个问题:
public String saveCandidate(Model model, @ModelAttribute Candidate candidate) {
Candidate candidate2 = candidateService.findById(candidate.getId());
candidate.setName(candidate2.getName());
candidate.setSurname(candidate2.getSurname());
candidate.setPhone(candidate2.getPhone());
candidate.setResumeUrl(candidate2.getResumeUrl());
candidateService.update(candidate2);
return "candidateMenu";
}
但我认为这是解决问题的非常糟糕的方法。
P.S。我知道fetchType.lazy很糟糕,但我不想替换它。
答案 0 :(得分:1)
您需要先从数据库加载实体,然后让spring将请求参数绑定到您的实体属性。
所以下面的内容可能会起作用
@ModelAttribute
public Candidate loadCandidate(@RequestParam(value="id",required=false) Long id) {
Candidate candidate=null;
if(id!=null){
candidate=candidateService.findById(id);
}
else{
candidate=new Candidate();
}
return candidate;
}
@RequestMapping(.......)
public String saveCandidate(Model model, @ModelAttribute Candidate candidate) {
candidateService.update(candidate);
return "candidateMenu";
}
由于loadCandidate()
方法使用@ModelAttribute
注释进行注释,因此在控制器中的任何请求映射处理程序之前将调用loadCandidate()
。
所以在你的情况下,loadCandidate()
saveCandidate()