日期:2014-05-16 浏览次数:20582 次
一般在双向关联的情况下,都要在一方设置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