hibernate 双向一对多的实现
来源:互联网 发布:linux安装apt get命令 编辑:程序博客网 时间:2024/06/05 11:40
在测试Hibernate的一对多双向关联映射时,碰到很有趣的问题,跟inverse属性直接相关。
1、People.hbm.xml
<hibernate-mapping default-lazy="false">
<class name="com.persistent.People" table="people">
<id name="id" column="peopleId" unsaved-value="0">
<generator class="increment">
</generator>
</id>
<property name="name" column="name"></property>
<set name="addresses" cascade="save-update">
<key column="peopleId" not-null="true" />
<one-to-many class="com.persistent.Address"/>
</set>
</class>
</hibernate-mapping>
2、Address.hbm.xml
<hibernate-mapping>
<class name="com.persistent.Address" table="address">
<id name="id" column="addressId" unsaved-value="0">
<generator class="increment">
</generator>
</id>
<many-to-one name="people" column="peopleId" insert="false" update="false"></many-to-one>
<property name="addressName" column="addressName"></property>
<property name="codeNumber" column="codeNumber"></property>
</class>
</hibernate-mapping>
3、People.java和Address.java
public class People ...{
private long id;
private String name;
private Set addresses = new HashSet();
...
}
public class Address ...{
private long id;
private People people;
private String addressName;
private String codeNumber;
...
}
4、数据库结构
people表:{peopleId,name}
address表:{addressId,peopleId,addressName,codeNumber}
5、测试代码
People people = new People();
people.setName("linda");
Address address = new Address();
address.setAddressName("yunnan");
address.setCodeNumber("564123");
address.setPeople(people);
people.getAddresses().add(address);
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();
session.save(people);
session.getTransaction().commit();
6、运行结果
上面测试代码运行起来正确:
Hibernate: select max(peopleId) from people
Hibernate: select max(addressId) from address
Hibernate: insert into people (name, peopleId) values (?, ?)
Hibernate: insert into address (addressName, codeNumber, peopleId, addressId) values (?, ?, ?, ?)
Hibernate: update address set peopleId=? where addressId=?
如果将People.hbm.xml映射改写一下:
<set name="addresses" cascade="save-update" inverse="true">
<key column="peopleId" not-null="true" />
<one-to-many class="com.persistent.Address"/>
</set>
不同之处在于添加了inverse="true",结果:
Hibernate: select max(peopleId) from people
Hibernate: select max(addressId) from address
Hibernate: insert into people (name, peopleId) values (?, ?)
Hibernate: insert into address (addressName, codeNumber, addressId) values (?, ?, ?)
可以看到,peopleId并没有写入到关联的address当中,数据库address表中相应记录的peopleId字段为空。
7、分析
在Hibernate中,术语inverse是反转的意思,在关联关系中,inverse="false"为主控方,由主控方负责维护对象的关联关系。所以上面的映射文件改动之后,address为主控方,people为被控方,但是测试代码只进行了一个保存操作session.save(people),这是针对people的,因此无法正确级联保存address。而原来的映射文件中(虽然没有明确指明,Hibernate默认inverse="false"),people为主控方,因此保存people时它会保证关联的address的正确保存。
也就是说,Hibernate仅仅按照主控方对象的状态的变化来同步更新数据库。按照原来的映射文件,people.getAddresses().add(address),即主控方对象的状态发生了改变,因此数据库会跟着对象状态的变化来同步更新数据库;而address.setPeople(people),即被控方对象的状态发生了改变,它是不能触发对象和数据库的同步更新的。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhaosg198312/archive/2008/12/10/3491579.aspx
- hibernate 双向一对多的实现
- hibernate 双向一对多的实现
- hibernate 双向一对多的实现
- hibernate实现双向一对多的映射
- Hibernate一对多(双向)
- Hibernate一对多(双向)
- Hibernate一对多(双向)
- Hibernate -- 一对多的双向关联关系
- Hibernate 双向一对多表的关联
- Hibernate双向的一对多关系映射
- Hibernate一对多双向关联
- Hibernate一对多双向关联
- Hibernate一对多双向关联
- Hibernate一对多双向关联
- Hibernate一对多双向关联
- Hibernate一对多双向关联
- hibernate双向一对多关联
- hibernate一对多双向注解
- 依赖,关联,聚合,组合
- C生成DLL供C#或VB调用
- 常用正则表达式(转载)
- C# 增 @ 删 @ 改 @ 查
- 电子电路基础知识
- hibernate 双向一对多的实现
- 我以我学以自强
- Lotus Notes 8.5.1 安装失败的解决方案
- 湘湘
- 解决VS2008中Web项目中App_Code目录问题
- C++test 学习之桩函数
- 如何将网站提交到搜索引擎
- 存储过程在java和C#中的调用
- ofstream写文件