经过几天的折磨来解决这个问题,并阅读了我所能找到的一切,所以我决定问。我很难理解我在Hibernate站点上读到的内容,所以我会解释一下我的情况。
我有一个包含对象student的对象program
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)
@JoinColumn(name = "PROGRAM_FK", nullable = false)
private Program program;在我的服务方法中,我只希望学生更改/更新程序:
public void edit(Student student) {
Session session = sessionFactory.getCurrentSession();
// Retrieve existing student via id
Student existingStudent = (Student) session.get(Student.class, student.getStudentId());
// Assign updated program to this student
existingStudent.setProgram(student.getProgram()); <-- This is not working as I would want it! -->
session.merge(existingStudent);
}我想改变学生的程序,但不是程序本身。我怎样才能做到这一点?有谁能告诉我,在这种特殊情况下,谁是父母,谁是孩子?我应该使用CascadeType.MERGE吗?我应该使用merge()方法还是其他方法?我无法从阅读文档中推断出这一点,如果有人能很好地解释这个特殊的案例,那么我最终可以理解它.谢谢。
程序对象:
@OneToMany(mappedBy="program")
private Set<Student> students;我从控制器调用我的编辑方法:
@RequestMapping(value="/edit", method = RequestMethod.POST, params="edit")
public String postEditStudent(
@Validated({Student.StudentEditChecks.class}) @ModelAttribute("studentAttribute") Student student,
BindingResult result,
Model model) {
logger.debug("Received request to edit student");
if (result.hasErrors()) {
model.addAttribute("programList", programService.getAll());
return "editStudent";
}
else {
studentService.edit(student);
return "redirect:/essays/main/student/list";
}
}发布于 2014-02-04 11:38:38
主要的问题是,您使用的输入包含了太多的信息以满足您的需要。这让一切都很混乱。
你想要做的就是为一个现有的学生设置一个现有的程序。这个任务唯一需要的输入是学生ID和程序ID。如果只有这些输入,解决方案就会变得很明显:
@Transactional
public void setProgramOnStudent(Long studentId, Long programId) {
Student student = (Student) session.get(Student.class, studentId);
Program program = (Program) session.load(Program.class, programId);
student.setProgram(program);
}请注意,我使用的是load()而不是get()来加载程序,因为您甚至不需要程序的th状态,只需要对现有程序的引用。它也可以与get()一起工作,但是它会执行一个额外的无用的seelct查询来加载程序的状态。
https://stackoverflow.com/questions/21550585
复制相似问题