首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Spring + Hibernate应用中正确修改带有@ManyToOne关系的对象

在Spring + Hibernate应用中正确修改带有@ManyToOne关系的对象
EN

Stack Overflow用户
提问于 2014-02-04 10:59:48
回答 1查看 1.3K关注 0票数 1

经过几天的折磨来解决这个问题,并阅读了我所能找到的一切,所以我决定问。我很难理解我在Hibernate站点上读到的内容,所以我会解释一下我的情况。

我有一个包含对象student的对象program

代码语言:javascript
复制
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)
@JoinColumn(name = "PROGRAM_FK", nullable = false)
private Program program;

在我的服务方法中,我只希望学生更改/更新程序:

代码语言:javascript
复制
 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()方法还是其他方法?我无法从阅读文档中推断出这一点,如果有人能很好地解释这个特殊的案例,那么我最终可以理解它.谢谢。

程序对象:

代码语言:javascript
复制
@OneToMany(mappedBy="program")
private Set<Student> students;

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

代码语言:javascript
复制
    @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";
        }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-04 11:38:38

主要的问题是,您使用的输入包含了太多的信息以满足您的需要。这让一切都很混乱。

你想要做的就是为一个现有的学生设置一个现有的程序。这个任务唯一需要的输入是学生ID和程序ID。如果只有这些输入,解决方案就会变得很明显:

代码语言:javascript
复制
@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查询来加载程序的状态。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21550585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档