在Spring MVC + Hibernate应用程序中正确修改具有@ManyToOne关系的对象 [英] Properly modify object with @ManyToOne relationship in Spring MVC + Hibernate app

查看:144
本文介绍了在Spring MVC + Hibernate应用程序中正确修改具有@ManyToOne关系的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

经过几天的酷刑来解决这个问题,并阅读所有我能找到的所以我决定问。我无法理解我在这里阅读的内容 Hibernate site ,所以我会解释我的情况。



我有object student ,它包含对象程序

  @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE},fetch = FetchType.EAGER)
@JoinColumn(name =PROGRAM_FK,nullable = false)
private程序程序;

在我的服务方法中,我想为学生更改/更新程序:

  public void edit(Student student){
Session session = sessionFactory.getCurrentSession();

//通过id $ b $检索现有的学生studentStateStudent =(Student)session.get(Student.class,student.getStudentId());

//为此学生分配更新的程序
existingStudent.setProgram(student.getProgram()); < - 这不是我想要的! - >

session.merge(existingStudent);
}

我想要更改学生的程序 ,但不是程序本身。我怎样才能做到这一点?有人可以告诉我,在这种特殊情况下,谁是父母,谁是孩子?我应该使用CascadeType.MERGE吗?我应该使用merge()方法还是其他?我无法从阅读文档中推断出这一点,如果有人会在这种特殊情况下如此善意地解释它,那么我终于可以理解它了......谢谢。



程序对象:

  @OneToMany(mappedBy =program)
private Set< Student>学生们;

我从控制器调用我的编辑方法:



pre $ @RequestMapping(value =/ edit,method = RequestMethod.POST,params =edit)
public String postEditStudent(
@Validated {Student.StudentEditChecks.class})@ModelAttribute(studentAttribute)学生学生,
BindingResult结果,
模型模型){

logger.debug(学生);

if(result.hasErrors()){
model.addAttribute(programList,programService.getAll());
返回editStudent;
}
else {
studentService.edit(student);
返回重定向:/ essays / main / student / list;
}
}


解决方案

主要的问题是你使用的输入包含太多的信息,你想做什么。这使得一切都变得混乱。

您只需要在现有的学生身上设置现有的课程。您需要完成此任务的唯一输入是学生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);

$ / code>

请注意,我使用 load()而不是 get()来加载程序,因为你不需要程序的状态,只需要引用已有的程序。它也可以和 get()一起工作,但它会执行一个额外的无用的seelct查询来加载程序状态。


After days of torture to resolve this issue and reading everything I could find on SO I decided to ask. I'm having trouble understanding what I read here on Hibernate site, so I'll explain my situation.

I have object student that contains object program:

@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)
@JoinColumn(name = "PROGRAM_FK", nullable = false)
private Program program;

In my service method I want o change/update only program for a student:

 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);
 }

I want to change the program for the student, but not the program itself. How can I achieve this? And can someone please tell me, in this particular situation, who is parent and who is child? Should I use CascadeType.MERGE at all? Should I use merge() method or something else? I can't deduce this from reading documentation, if someone would be so kind to explain it on this particular case, so I can finally understand it... Thank you.

Program object:

@OneToMany(mappedBy="program")
private Set<Student> students;

I'm calling my edit method from controller:

    @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";
        }
    }

解决方案

The main problem is that you use inputs that contain too much information for what you want to do. And that makes everything confusing.

All you want to do is setting an existing program on an existing student. The only inputs you need for this task are the student ID and the program ID. And if you had only those inputs, the solution would become obvious:

@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);
}

Note that I used load() and not get() to load the program, because you don't ven need th state of the program, only a reference to the existing program. It would also work with get(), but it would execute an additional, useless seelct query to load the state of the program.

这篇关于在Spring MVC + Hibernate应用程序中正确修改具有@ManyToOne关系的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆