读完 Java对象持久化技术详解6.1节,写一下读书笔记:
多对一 单向关联 匹配 关系数据库中的外键参照关系。
在关系数据库中,只存在外键参照关系,而且是由many--->one,是单向关联。
以Customer和Order为例。
单向关联中,Order中包含一个customer属性。这样定义了一个Order到Customer的关联,是多对一的。Customer中未包含Order属性.
在Order.hbm.xml中,要进行关联映射Order类与ORDERS表。
单向关联中,Order中包含一个customer属性。这样定义了一个Order到Customer的关联,是多对一的。Customer中未包含Order属性.
在Order.hbm.xml中,要进行关联映射Order类与ORDERS表。
id------ID customer------CUSTOMER_ID
映射 customer------CUSTOMER_ID需要 使用 many-to-one
many-to-one用来建立customer属性和ORDERS表的外键CUSTOMER_ID之间的映射
<many-to-one
name = "customer" //待映射的持久化类的属性名
column = "CUSTOMER_ID" //设定和该属性对应的表的外键
class = "Customer" //设定该属性的类型
not-null = "true" //表示customer属性不能为null,默认为false
cascade = "all" //级联更新与Order类对象相关联的对象
/>
一个概念:
临时对象(transient)
刚刚通过new( )创建,并且未被持久化的对象。
Customer customer = new Customer(); //transient
session.save(customer); //执行完该语句后,customer成为持久化对象
//------------------不同的配置出现的不同情况-----------------------
cascade取默认值的情况
<many-to-one
Order order = new Order();
order.setCustomer(customer);
session.save(order);
Hibernate持久化order时,
不会自动持久化与其相关联的其他对象,因为没有显示设置cascade属性的相关值。
这样cascade取默认值none,当持久化order时,会执行类似如下语句:
insert into ORDERS (ID,CUSTOMER_ID) values (1,null
)
这违反了数据库完整性约束,因为ORDERS表中设置的CUSTOMER_ID为 not null
抛出异常:
net.sf.hibernate.PropertyValueException: not-null property references a null or transient
value: Order.customer
删除 not-null = "true"后,
会把order与customer一起持久化。
insert into CUSTOMERS(ID,NAME) values( 1
, "
haha")
insert into ORDERS( ID, CUSTOMER_ID) values (1,1
)
<many-to-one
Order order = new Order();
order.setCustomer(customer);
session.save(order);
Hibernate持久化order时,
insert into ORDERS (ID,CUSTOMER_ID) values (3,null
)
这次成功持久化了order对象,不再抛出PropertyValueException,因为ORDERS表的CUSTOMER_ID允许null值出现
但当Hibernate自动清理(flush)缓存中所有持久化对象时,抛出新的异常:
net.sf.hibernate.TransientObjectException: object references an unsaved transient instance -
save the transient instance before flushing: Customer
flush -- Hibernate按照内存中持久化对象的状态
来同步更新数据库.
Hibernate发现持久化对象order引用transient对象customer,而ORDERS表中相应的记录的
CUSTOMER_ID字段为null,也就是说内存中的持久化对象的状态与数据库中的记录不一致。
而且在这种情况下,Hibernate没办法使两者同步,因为Hibernate不会自动持久化customer对象,
所以,Hibernate抛出 TransientObjectException异常。
这时需要设置cascade属性来解决问题
<many-to-one
name = "customer" //待映射的持久化类的属性名
column = "CUSTOMER_ID" //设定和该属性对应的表的外键
class = "Customer" //设定该属性的类型
cascade = "save-update"
//当保存或更新当前对象时
//级联保存或更新与Order类对象相关联的对象
/>
这样当执行
Customer customer = new Customer();
//transient
customer.setName("haha");
Order order = new Order();
order.setCustomer(customer);
session.save(order);
name = "customer" //待映射的持久化类的属性名
column = "CUSTOMER_ID" //设定和该属性对应的表的外键
class = "Customer" //设定该属性的类型
/>
Customer customer = new Customer();
//transient
name = "customer" //待映射的持久化类的属性名
column = "CUSTOMER_ID" //设定和该属性对应的表的外键
class = "Customer" //设定该属性的类型
not-null = "true" //表示customer属性不能为null,默认为false
/>
Customer customer = new Customer();
//transient
相关推荐
hibernate外键实现一对一单向关联关系源码
使用eclipse获取mysql数据库中的表结构以及主外键
关于关系型数据库基本知识(主键、外键、一对一、一对多、多对一等),适合了解数据库最基本知识的初学者阅读
Hibernate 多对一外键单向关联 Hibernate 多对一连接表单向关联 Hibernate 多对多单向关联 Hibernate 一对一外键双向关联 Hibernate 一对一主键双向关联 Hibernate 一对一连接表双向关联 Hibernate 一对多外键双向...
数据库主外键详解,带代码片段。让你直观了解数据库的主外键设置
Hibernate 一对多 外键 单向关联,有例子。
│ ├─ 多对一外键单向关联 │ ├─ 多对一连接表单向关联 │ └─ 多对多单向关联 └─双向关联 ├─ 一对一外键双向关联 ├─ 一对一主键双向关联 ├─ 一对一连接表双向关联 ├─ 一对多外键双向关联 ├─ 一对...
内包含外键约束模式,数据库的视图基本操作
在比较复杂的数据库中,经常要处理表中的外键关系,本人写了一些处理外键的方法,还忘诸位多多指点……
数据库主键和外键设计的原则
hibernate外键实现一对一双向关联关系源码
本文介绍在在MySQL数据库中定义数据表、设置索引、定义外键、级联等操作。
本文档是数据库的外键约束方式指南 需要的朋友请下载 保证可用
hibernate基于主外键的一对多/多对一关联
关系模型Relational_Model,主键Primary_Key,外键Foreign_Key【关系数据库SQL教程2】
NULL 博文链接:https://12345678.iteye.com/blog/723871
Mysql数据库如何删除某一个数据库的所有外键并不删除相应的索引,一个sql脚本解决,无需知道外键的名称。
本文介绍了在MySQL数据库中定义外键的方法。
NULL 博文链接:https://zhouhaitao.iteye.com/blog/1171227
父表中的外键,是子表中的主键。在父表中的外键,可以出现多次。主键是不能有重复的。