JPA中OneToMany/ManyToMany双向关联的更新与保存问题
一对多场景
假设存在Teacher和Student表,一个教师对应多个学生,关联映射如下:
@Entity @Table(name = "teacher") public class Teacher { @OneToMany(mappedBy="teacher") private Set<Student> student = new HashSet<>(); }
@Entity @Table(name = "student") public class Student { @ManyToOne private Teacher teacher; }
当创建新Student实例Student student = new Student();时,仅保存Student即可,不需要同时更新并保存Teacher。
原因是:在JPA关联关系中,@ManyToOne标注的Student是关联的拥有方(负责维护数据库中外键字段),而Teacher的@OneToMany(mappedBy="teacher")是被拥有方(不负责维护关联关系)。只要给新Student设置好teacher属性,然后调用studentRepository.save(student),数据库中Student表的外键字段就会被正确赋值,关联关系生效。
如果想要保持内存中Teacher对象的student集合与数据库状态一致(比如后续业务逻辑需要用到这个集合),可以手动执行teacher.getStudent().add(student),但这一步不是必须的,不影响数据库的关联关系存储。
多对多场景
若关联为多对多,映射如下:
@Entity @Table(name = "teacher") public class Teacher { @ManyToMany(mappedBy="teacher") private Set<Student> student = new HashSet<>(); }
@Entity @Table(name = "student") public class Student { @ManyToMany @JoinTable( name="teacher_student", joinColumns = @JoinColumn(name = "teacher_id"), inverseJoinColumns = @JoinColumn(name = "student_id") ) private Set<Teacher> teacher = new HashSet<>(); }
仅从Student侧保存是否可行?
可行。因为Student是多对多关联的拥有方(通过@JoinTable定义了关联表结构,负责维护关联表)。只要给Student的teacher集合添加已存在的Teacher实例,调用studentRepository.save(student),Hibernate就会自动向关联表teacher_student中插入对应的关联记录。
先执行teacherRepository.save(teacher),再执行student.setTeacher(teacher);studentRepository.save(student);会出现什么情况?
这会正常建立Teacher和Student的关联关系,关联表teacher_student中会新增一条对应两者ID的记录。
因为Teacher已经被持久化到数据库,此时给Student的teacher集合添加该Teacher并保存Student,作为拥有方的Student会触发关联表的插入操作,完成关联关系的存储。
内容的提问来源于stack exchange,提问作者itsmarziparzi

