对于1-N关联,Hibernate推荐使用双向关联,而且不要让1的一方控制关联关系,而使用多的一方控制关联关系。
a. 一的一方 表示班级
@Entity @Table(name="team_1") public class Team { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="team_id") private int id; private String name; @OneToMany(mappedBy="team",targetEntity=Student.class,cascade=CascadeType.ALL) private Set<Student>students=new HashSet<Student>(); //省略set get方法 }b.多的一方 表示学生
@Entity @Table(name="student_1") public class Student { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="student_id") private int id; private String name; @ManyToOne(targetEntity=Team.class,fetch=FetchType.LAZY) @JoinColumn(name="team_id",nullable=false,referencedColumnName="team_id") private Team team; //省略set get方法 }c.持久化代码
Team team=new Team(); team.setName("20150225"); session.persist(team); Student student=new Student(); student.setName("zhangsan"); student.setTeam(team); Student student2=new Student(); student.setName("lisi"); student2.setTeam(team); session.save(student); session.save(student2); tx.commit();在持久化代码中,首先创建了一的一方 team对象,并对他进行了保存, 然后创建了多的一方,并进行了保存。这是符合客观事实的,即首先要有班级,然后才能有学生从属于某个班级。如果不这样做,那么将会抛出异常。对于这样的程序,应注意:
双向N-N关系需要两端都使用Set集合属性,两端都增加对集合属性的访问。双向N-N关系只能采用连接表的方式。
双向N-N关联需要在两端分别使用@ManyToMany修饰Set集合属性,并在两端都是用@JoinTable显示映射连接表。如果程序希望一端放弃控制关联关系,则可在这一端的@ManyToMany注解中指定mappedby属性,这一端就无须、也不能使用@JoinTable映射连接表了。
下面示例表示课程与学生的关系。一个课程可由多个学生选择,一个学生可以选择多门课程
@Entity @Table(name="course_2") public class Course { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="course_id") private int id; private String name; @ManyToMany(targetEntity=Student.class) @JoinTable (name="student_course", joinColumns=@JoinColumn(name="courseId",referencedColumnName="course_id"), inverseJoinColumns=@JoinColumn(name="studentId",referencedColumnName="student_id") ) private Set<Student> courses=new HashSet<Student>();
@Entity @Table(name="student_2") public class Student { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="student_id") private int id; private String name; @ManyToMany(targetEntity=Course.class,cascade=CascadeType.ALL) @JoinTable (name="student_course", joinColumns=@JoinColumn(name="studentId",referencedColumnName="student_id"), inverseJoinColumns=@JoinColumn(name="courseId",referencedColumnName="course_id") ) private Set<Course> courses=new HashSet<Course>();
(1)对于关联实体而言,Hibernate默认不会启用级联操作,当父对象被保存时,他关联的子实体不会被保存。为了启用不同持久化操作的级联行为,Hibernate定了如下级联风格
(2)Hibernate还支持一个特殊的级联策略:删除孤儿对象(可通过@OneToMany,@OneToOne的orphanRemoval属性来启动级联策略)
<span style="font-size:18px;">@OneToMany(mappedBy="team",targetEntity=Student.class,cascade=CascadeType.ALL,orphanRemoval=true)</span>
(3)对于级联的设定,Hibernate有如下建议