Hibernate映射的关系问题
2015-04-11 11:05
330 查看
本文章目的是为了测试一对多的关系问题,所以配置信息都是以测试为目的的。
数据库:mysql
实体类:部门实体 Dept,员工实体 Employee
环境准备:
上面的配置是一对多双向关联,呆会通过更改配置文件测试 一对多双向关联;多对一单向关联;一对多单向关联;三个的保存操作
测试:
1.一对多双向关联保存
2.多对一单向关联;从多的一方保存
配置:多对一单向关联,顾名思义,就是在多的一方Employee保存,以及维护关系,所以在上面Dept类中可以设置private Set emps = new HashSet();该集合属性,映射文件也响删除该配置。
注:这里只贴出测试方法,类名和类的变量和上面一致
3一对多单向关联
配置:在Employ实体类中可以删除, private Dept dept;该属性,相应的在映射文件中也删除配置,
注:实际上跟上面第一个测试是一样的测试代码,不同点是在配置文件上
总结:
1 没有设置cascade属性的话,在任何一方保存都会出现这个异常,因为在以一方维护,必须具有级联保存的权限
2 在一对多单向关联单向关联中,设置了cascade=”save-update”外,不能将inverse设置为true,这个属性的作用是将控制权反转,默认为false,因为没了控制权,也就不能维护关联关系了
一对多的关系体现得最彻底的是父与子的关系,也就是一个父亲对应多个儿子,多个儿子对应一个父亲,儿子一定有父亲,父不一定有子。所以从这个关系上来说应该是以多的一方来维护关系,所以测试的第三个例子一般很少用,即单向一对多。
以上是自己的总结,如有疑问欢迎吐槽,渴望碰撞。
数据库:mysql
实体类:部门实体 Dept,员工实体 Employee
环境准备:
1 hibernate.cfg.xml配置文件 <hibernate-configuration> <session-factory> <!-- 1. 数据库连接配置 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///jdbc_demo</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!-- 数据库方法配置 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- 2. 其他相关配置 --> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 3. 加载所有映射 在测试类中手动的加载配置文件--> </session-factory> </hibernate-configuration>
2 Dept实体类 public class Dept { private int deptId; private String deptName; // 【一对多】 部门对应的多个员工 private Set<Employee> emps = new HashSet<Employee>(); 省略setter,getter...; 省略构造方法; } Employee 实体类 public class Employee { private int empId; private String empName; private double salary; // 【多对一】员工与部门 private Dept dept; 省略setter,getter...; 省略构造方法; }
3 映射文件 Dept映射 <hibernate-mapping package="cn.itcast.b_one2Many"> <class name="Dept" table="t_dept"> <id name="deptId"> <generator class="native"></generator> </id> <property name="deptName" length="20"></property> <set name="emps" cascade="save-update" inverse="true"> <key column="dept_id"></key> <one-to-many class="Employee"/> </set> </class> </hibernate-mapping> Employee 映射 <hibernate-mapping package="cn.itcast.b_one2Many"> <class name="Employee" table="t_employee"> <id name="empId"> <generator class="native"></generator> </id> <property name="empName" length="20"></property> <property name="salary" type="double"></property> <many-to-one name="dept" column="dept_id" class="Dept" cascade="save-update"></many-to-one> </class> </hibernate-mapping>
上面的配置是一对多双向关联,呆会通过更改配置文件测试 一对多双向关联;多对一单向关联;一对多单向关联;三个的保存操作
测试:
1.一对多双向关联保存
public class App1_save { private static SessionFactory sf; static { sf = new Configuration() .configure() .addClass(Dept.class) .addClass(Employee.class) // 测试使用,可以加载到映射文件,不用在hibernate.cfg.xml引入 .buildSessionFactory(); } // 保存, 部门方 【一的一方法操作】 @Test public void save() { Session session = sf.openSession(); session.beginTransaction(); // 部门对象 Dept dept = new Dept(); dept.setDeptName("应用开发部"); // 员工对象 Employee emp_zs = new Employee(); emp_zs.setEmpName("张三2"); Employee emp_ls = new Employee(); emp_ls.setEmpName("李四2"); // 关系 dept.getEmps().add(emp_zs); dept.getEmps().add(emp_ls); // 保存 session.save(dept); // 保存部门,部门下所有的员工;在配置文件中有加入cascade="save-update",进行级联保存跟新 session.getTransaction().commit(); session.close(); } } 保存成功。 /* sql: Hibernate: insert into t_dept (deptName) values (?) Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?) Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?) Hibernate: update t_employee set dept_id=? where empId=? Hibernate: update t_employee set dept_id=? where empId=? */
2.多对一单向关联;从多的一方保存
配置:多对一单向关联,顾名思义,就是在多的一方Employee保存,以及维护关系,所以在上面Dept类中可以设置private Set emps = new HashSet();该集合属性,映射文件也响删除该配置。
注:这里只贴出测试方法,类名和类的变量和上面一致
@Test public void save4() { Session session = sf.openSession(); session.beginTransaction(); // 部门对象 Dept dept = new Dept(); dept.setDeptName("应用开发部"); // 员工对象 Employee emp_zs = new Employee(); emp_zs.setEmpName("张三2"); Employee emp_ls = new Employee(); emp_ls.setEmpName("李四2"); // 关系,多的一方维护 emp_zs.setDept(dept); emp_ls.setDept(dept); // 保存 session.save(emp_zs);//在映射文件中一定要配置casecade="save-update",否则不能实现关系的维护 session.save(emp_ls); session.getTransaction().commit(); session.close(); } 保存成功,可以看出从多的一方保存,可以省去两条update语句。所以一般由多的一方维护关系,即在一的一方Dept中,set标签中设置inverse="true" /* Hibernate: insert into t_dept (deptName) values (?) Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?) Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?) */
3一对多单向关联
配置:在Employ实体类中可以删除, private Dept dept;该属性,相应的在映射文件中也删除配置,
注:实际上跟上面第一个测试是一样的测试代码,不同点是在配置文件上
@Test public void save3() { Session session = sf.openSession(); session.beginTransaction(); // 部门对象 Dept dept = new Dept(); dept.setDeptName("应用开发部"); // 员工对象 Employee emp_zs = new Employee(); emp_zs.setEmpName("张三2"); Employee emp_ls = new Employee(); emp_ls.setEmpName("李四2"); // 关系 dept.getEmps().add(emp_zs); dept.getEmps().add(emp_ls); // 保存 session.save(dept); // 保存部门,部门下所有的员工 session.getTransaction().commit(); session.close(); } /* Hibernate: insert into t_dept (deptName) values (?) Hibernate: insert into t_employee (empName, salary) values (?, ?) Hibernate: insert into t_employee (empName, salary) values (?, ?) Hibernate: update t_employee set dept_id=? where empId=? Hibernate: update t_employee set dept_id=? where empId=? */
总结:
1 没有设置cascade属性的话,在任何一方保存都会出现这个异常,因为在以一方维护,必须具有级联保存的权限
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing:
2 在一对多单向关联单向关联中,设置了cascade=”save-update”外,不能将inverse设置为true,这个属性的作用是将控制权反转,默认为false,因为没了控制权,也就不能维护关联关系了
一对多的关系体现得最彻底的是父与子的关系,也就是一个父亲对应多个儿子,多个儿子对应一个父亲,儿子一定有父亲,父不一定有子。所以从这个关系上来说应该是以多的一方来维护关系,所以测试的第三个例子一般很少用,即单向一对多。
以上是自己的总结,如有疑问欢迎吐槽,渴望碰撞。
相关文章推荐
- 关于hibernate映射继承关系时独立的子类配置文件的问题
- 在使用Hibernate时,因为一个查询需要更多的表连接而要使用SQL来解决性能问题。然而返回的结果集中包含了没有映射的Entity类中的表字段,在这个SQL中还有使用如何将层次关系的父子结点显示为横行
- Hibernate关系映射时出现的问题
- 有关Hibernate映射关系 no session or session was closed问题解绝方法
- 解决使用Hibernate QBC复合查询含有联合主键映射关系实体的问题
- 关于hibernate的关系映射的问题一些理解和笔记
- Hibernate的对象-关系映射文件中出现的问题
- Hibernate关系映射和HQL
- 对象/关系映射—Hibernate
- 阿翔编程学-Hibernate中多对多关系的常见问题
- 2-Hibernate的各种关系映射
- Hibernate ORM 对象-关系 映射
- Hibernate中多对多关系的常见问题 (摘)
- 使用Hibernate进行对象的关系映射(2)
- 精通Hibernate之映射继承关系一
- Hibernate中多对多关系的常见问题
- 使用Hibernate进行对象的关系映射(1)
- Java类型、Hibernate映射类型以及SQL类型之间的对应关系
- hibernate复杂映射关系下的删除操作和list类型映射的注意点
- 精通Hibernate之映射继承关系三