Hibernate 在Spring MVC+;中正确修改具有@manytone关系的对象;休眠应用程序
经过几天的折磨,我终于解决了这个问题,阅读了所有我能找到的东西,所以我决定去问。我很难理解我在这里读到的内容,所以我会解释我的情况 我有一个objectHibernate 在Spring MVC+;中正确修改具有@manytone关系的对象;休眠应用程序,hibernate,spring-mvc,updating,many-to-one,Hibernate,Spring Mvc,Updating,Many To One,经过几天的折磨,我终于解决了这个问题,阅读了所有我能找到的东西,所以我决定去问。我很难理解我在这里读到的内容,所以我会解释我的情况 我有一个objectstudent,它包含objectprogram: @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER) @JoinColumn(name = "PROGRAM_FK", nullable = false) private Pro
student
,它包含objectprogram
:
@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);
}
主要问题是,您使用的输入包含的信息太多,无法满足您的需要。这让一切都变得扑朔迷离 你所要做的就是在现有的学生身上设置一个现有的程序。此任务所需的唯一输入是学生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()
来加载程序,因为您甚至不需要程序的状态,只需要对现有程序的引用。它也可以使用get()
,但是它会执行一个附加的、无用的seelct查询来加载程序的状态。您能否提供在哪里调用编辑方法以及如何调用的详细信息。调用edit方法时,student参数是否设置了程序。你是怎么推断它不起作用的。你有什么例外吗?学生是拥有者,所以在上面设置参考似乎是正确的。你能发布程序代码以及它是如何引用学生的吗?@Pratik我只是在控制器中这样调用它:studentService.edit(Student)代码>没有其他内容。我的具体实现有不同的错误,但我在这里介绍的是问题的核心,否则,问题将是巨大的。如何用这种特殊关系更新对象,这是我想了解的。@kostja我更新了我的帖子。@Pratik我更新了我的帖子。这是一个很好的建议,谢谢。在对现有学生设置现有程序后,我应该使用什么会话方法将更改保存到db?我应该如何为该方法设置CascadeType@jbnizet以上代码已足够。您不需要调用任何save、persist、merge或其他任何函数。附加的实体是透明持久的,因此应用于学生状态的更改将在事务结束时自动刷新并提交到数据库。上述内容也不依赖于任何级联。它所做的只是改变一个实体的一个字段的值:Student。瀑布是无关紧要的。
@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";
}
}
@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);
}