Hibernate4中的onetomany的理解

分析场景:

departments对应多个员工employees:

departments.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.domain">

<class name="Department" table="departments">
<cache usage="read-only"/>
<id name="id" unsaved-value="0">
<generator class="native" />
</id>
<property name="name" />
 
<set name="employees"  cascade="save-update" >
<key column="depart_id"/>
<one-to-many class="Employee"/>
</set>

</class>
</hibernate-mapping>

下面是employees.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"hibernate-mapping-3.0.dtd">
<hibernate-mapping 
package="cn.itcast.domain">

<class name="Employee" table="employees">
<cache usage="read-only"/>
<id name="id" column="id" unsaved-value="0">
<!--  
<generator class="native"/>
-->
<generator class="hilo"/>
</id>
<!--  
<discriminator column="type" type="int"/>
-->
<property name="name"/>
<property name="age"/>
<many-to-one name="depart" column="depart_id" lazy="false" fetch="join"/>


<union-subclass name="Skiller" table="skiller">
<property name="skill"/>
</union-subclass>

<union-subclass name="Sales" table="sales">
<property name="sell"/>
</union-subclass>
</class>
</hibernate-mapping>

测试代码:

static void add() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//Department dep=(Department)session.get(Department.class, 1);

Department depart = new Department();
depart.setName("depart"+new Date().toLocaleString());

Set emps = new HashSet();
Employee emp = new Employee();
emp.setName("emp name:jimmy "+new Date().toLocaleString());
emp.setAge(10);

Employee emp1 = new Employee();
emp1.setName("emp name:kaka"+new Date().toLocaleString());
emp1.setAge(10);


emps.add(emp1);
emps.add(emp);

depart.setEmployees(emps);
session.save(depart);
//*/

tx.commit();
} finally {
if (session != null)
session.close();
}
}

输出语句:

Hibernate: insert into departments (name) values (?)
Hibernate: select next_hi from hibernate_unique_key for update
Hibernate: update hibernate_unique_key set next_hi = ? where next_hi = ?                  //这是hibernate4版本的多出的表
Hibernate: insert into employees (name, age, depart_id, id) values (?, ?, ?, ?)
Hibernate: insert into employees (name, age, depart_id, id) values (?, ?, ?, ?)
Hibernate: update employees set depart_id=? where id=?
Hibernate: update employees set depart_id=? where id=?

分析:看出有5条语句,先插入一条departments ,然后由于部门的set集合中 cascade="save-update" ,所以级联更新对应的员工数据,也即后面的两条插入员工数据,但是由于set集合默认的inverse为false,即有部门对象负责关联数据的维护工作,也即负责更新employees 表中的depart_id字段的值,所以后面又出现了两条更新员工的depart_id的语句。

问:如果去掉cascade="save-update" 怎么样?

答:报错org.hibernate.TransientObjectException

再问:如果设置cascade="save-update",同时设置inverse="true",怎么样?

答:输出三条语句,因为inverse="true",意味着由员工维护自己多的一方的数据,也即 
部门department不再作为主控方,而将关联关系的维护工作交给关联对象employees 员工来完成。在保存department时,department不在关心employee的depart_id属性,必须由employee自己去维护,可是employee又没有emp.setDepart(depart);查询数据库可知道depart_id为null

 insert into departments (name) values (?)
insert into employees (name, age, depart_id, id) values (?, ?, ?, ?)
insert into employees (name, age, depart_id, id) values (?, ?, ?, ?)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值