首先,来看看部门(department)和雇员(employee)的ER关系图:
这个关系该的理解为:一个雇员拥有一个部门,一个部门对应多个雇员。从关系上理解,雇员为拥有方(the owning side),部门为被拥有方(the owned side)。当你用Hibenate4的annotation去配置映射关系的时候,有个需要注意的地方:@JoinColumn和@OneToMany中的mappedBy属性是不能同时存在的。也即,在拥有方(the owning side)你只能这么写:
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "department_id")
private Department department;
在被拥有方(the owned side)你只能这么写:
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
@Fetch(FetchMode.SUBSELECT)
@OrderBy("id")
private Set<Employee> employees = new LinkedHashSet<Employee>();
你可以用一下测试代码:
public class HibernateTest {
private static SessionFactory sf;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
Configuration cfg = new Configuration();
cfg.configure();
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
try {
sf = cfg.configure()
.addAnnotatedClass(Employee.class)
.buildSessionFactory(sr);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void test() {
Session s = sf.openSession();
Transaction tx = s.beginTransaction();
Department d = new Department();
d.setName("development");
Employee e = new Employee();
e.setAge(33);
e.setSex(1);
e.setCellphone("86186xxxxxxx8");
e.setLastname("Tian");
e.setFirstname("Max");
e.setEmail("max.tian@xxxx.com");
e.setDepartment(d);
s.persist(e);
tx.commit();
s.close();
}
}
关于mappedBy的理解:
- 只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性;
- mappedBy标签一定是定义在被拥有方(the owned side),他指向拥有方(the owning side);
- mappedBy的含义,应该理解为,拥有方能够自动维护跟被拥有方的关系;
- mappedBy跟JoinColumn/JoinTable总是处于互斥的。
数据库表结构:
-- Table: department
-- DROP TABLE department;
CREATE TABLE department
(
id integer NOT NULL,
name character varying(60),
CONSTRAINT department_pk PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE department
OWNER TO postgres;
-- Table: employee
-- DROP TABLE employee;
CREATE TABLE employee
(
id integer NOT NULL,
first_name character varying(60),
last_name character varying(60),
full_name character varying(120),
email character varying(255),
cell_phone character varying(15),
age smallint,
sex smallint,
department_id integer,
CONSTRAINT employee_pk PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE employee
OWNER TO postgres;