单向N:1无中间表映射
员工与部门的关系:假如员工只能属于一个部门,那么员工与部门之间是N:1的关系,如果只能从员工来找到员工所属的部门,而不是从部门来找到对应的员工,那么这就成了单向的N:1关联
Hibernate工具类(简单测试)
public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new Configuration().configure().buildSessionFactory(); } catch (Exception ex) { // Make sure you log the exception, as it might be swallowed System.out.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static Session getSession(){ SessionFactory sf=getSessionFactory(); return sf.openSession(); } }
员工
public class Employee { private Long id; private String name; private Department department; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } }
员工配置文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.longtech.hibernate.domain.Employee" table="Employee"> <id name="id" column="id" type="java.lang.Long" > <meta attribute="field-description">唯一标识</meta> <generator class="native"/> </id> <property name="name" type="java.lang.String" column="name" length="20"> <meta attribute="field-description">员工名称</meta> </property> <many-to-one name="department" column="dept_id" cascade="all"></many-to-one> </class> </hibernate-mapping>
部门
public class Department { private Long id; private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
部门配置文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.longtech.hibernate.domain.Department" table="Department"> <id name="id" column="id" type="java.lang.Long" > <meta attribute="field-description">唯一标识</meta> <generator class="native"/> </id> <property name="name" type="java.lang.String" column="name" length="20"> <meta attribute="field-description">部门名称</meta> </property> </class> </hibernate-mapping>
持久化类
Department dept=new Department(); dept.setName("department"); Employee emp1=new Employee(); emp1.setName("emp1"); emp1.setDepartment(dept); session.save(emp1);
在持久化类中,当执行session.save(emp1)的时候,如果没有指定cascade="all",那么执行的时候就会抛出org.hibernate.TransientObjectException的异常。
通过以上操作,就可以发现当执行了程序后,数据库里会生成两条记录。
而控制台会输入两条记录:
Hibernate: insert into Department (name) values (?) Hibernate: insert into Employee (name, dept_id) values (?, ?)
这个说明,如果使用了cassade="all",那么数据库会先插入Department记录,然后再插入员工,否则它就会报异常。其实这个逻辑是和jdbc操作数据库的时候是一样的。如果不先插入department,则会出来外键引用不到的情况。