日期:2014-05-16 浏览次数:20496 次
一般在双向关联的情况下,都要在一方设置mappedBy(name="xxx"),由对方主导映射关系。在多对一的情况下,一般在多的一方设置主导映射的关系(为了方便叙述,就这么叫它了,呵呵)。所谓主导这种映射关系,如group,user,就是由多的一方(user)里面产生一个外键参考一的一方(group)的主键,这时候user就是主导的一方,写mappedBy是被主导的一方。在多对多的情况下,随便由那方主导,在数据库表的结构上都是一样的,都会产生一个中间表,中间表有两个字段的联合主键,分别作为外键参考两个多的一方。
在一对多和多对多的双向关联的情况下,并且在cascade=CascadeType.ALL情况下,save不同方面(如主导关系一方或被主导的一方)在级联的具体表现上是不同的。分别来讨论一下。
先看一对多的双向关联关系,这里就拿group和user举例。
Group类如下:
package com.chen.hibernate.ormapping; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name = "t_group") public class Group { private int id; private String name; private Set<User> users = new HashSet<User>(); @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } // 设置mappedBy是被主导的一方 @OneToMany(mappedBy = "group", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) public Set<User> getUsers() { return users; } public void setUsers(Set<User> users) { this.users = users; } }
User类如下:
package com.chen.hibernate.ormapping; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name = "t_user") public class User { private int id; private String name; private Group group; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } //设置fetch为lazy,多的一方默认问eager @ManyToOne(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) @JoinColumn(name = "groupId") public Group getGroup() { return group; } public void setGroup(Group group) { this.group = group; } }
package com.chen.hibernate.ormapping; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; public class CRUDTest { private static SessionFactory sessionFactory = null; @BeforeClass public static void beforeClass() { new SchemaExport(new AnnotationConfiguration().configure()).create( false, true); sessionFactory = new AnnotationConfiguration().configure() .buildSessionFactory(); } @Test public void testSaveUser() { User user = new User(); user.setName("u1"); Group group = new Group(); group.setName("g1"); // 这里仅仅把group加到user中,而不需要group.getUsers().add(user);把当前的对象加入到group的set里 user.setGroup(group); Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); session.save(user); session.getTransaction().commit(); } // 再看看save被主导的一方会如何。 @Test public void testSaveGroup() { // 先new两个user,一个group,然后把user加到group中 User user = new User(); user.setName("u1"); User user2 = new User(); user2.setName("u2"); Group group = new Group(); group.setName("g1"); group.getUsers().add(user); group.getUsers().add(user2); // 注意,虽然两边都是级联的方式,但這裡的user也要把group设一下,不然,save(group)的时候,user表中的 // groupId字段仍是null user.setGroup(group); user2.setGroup(group); Sess