博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
6.1.1 无连接表的单向N--->1关联
阅读量:2445 次
发布时间:2019-05-10

本文共 2702 字,大约阅读时间需要 9 分钟。

单向N--->1关联,比如在一个办公室里工作的多个人对应一个地址。为了让两个持久化类支持这种关联映射,程序应该在N的一端的持久化类中增加一个属性,该属性引用1的一端的关联实体。

我们先将test库里的表删除:

然后新建一个web工程,并编写代码:

Person.java :

public class Person {		private int id;	private String name;	private int age;	private Address address;		public int getId() {		return id;	}	public void setId(int id) {		this.id = id;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public int getAge() {		return age;	}	public void setAge(int age) {		this.age = age;	}	public Address getAddress() {		return address;	}	public void setAddress(Address address) {		this.address = address;	}	}
Address.java :
public class Address {		private int addressId;	private String addressDetail;		public int getAddressId() {		return addressId;	}	public void setAddressId(int addressId) {		this.addressId = addressId;	}	public String getAddressDetail() {		return addressDetail;	}	public void setAddressDetail(String addressDetail) {		this.addressDetail = addressDetail;	}	public Address(String addressDetail) {		super();		this.addressDetail = addressDetail;	}	}
Person.hbm.xml :
Person端增加了Address属性,该属性不是一个普通的组件属性,而是引用另一个持久化类的类,Hibernate使用
<many-to-one.../>元素映射N--->1的关联实体,直接采用<many-to-one.../>元素来映射关联实体将会在N的一端的数据表中增加一个外键列,用于参照主表记录。直接使用<many-to-one.../>元素来映射N--->1关联时,Hibernate将无需使用连接表,直接使用外键关联策略来处理这种关联映射。

Address.hbm.xml :

Test.java :
public class Test {	public static void main(String[] args) {				Session session=HibernateSessionFactory.getSession();		Transaction txt=session.beginTransaction();		Person p=new Person();		p.setName("tom");		p.setAge(20);		Address a1=new Address("广州天河");//①		p.setAddress(a1);		session.persist(p);//③		Address a2=new Address("上海虹口");//②		p.setAddress(a2);		txt.commit();		HibernateSessionFactory.closeSession();	}}

上面程序创建了三个持久化实体,即一个Person对象,两个Address对象,程序只在③处保存了一次Person对象,从来不曾保存过Address对象。

程序在①处创建了一个瞬态的Address对象,当程序执行到③处时,系统准备保存Person对象,系统将要向persons表中插入一条记录------但该记录参照的主表记录还不曾保存(被参照的Address实体还处于瞬态),这时可能有如下两种情况发生:

① 系统抛出TransientObjectException异常:因为主表记录不曾插入,所以参照该记录的从表记录无法插入。

② 系统先自动级联插入主表记录,再插入从表记录。

因为上面的映射文件中指定了cascade="all",这意味着系统将先自动级联插入主表记录,也就是先持久化Address对象,再持久化Person对象。也就是说,Hibernate在③处将先执行一条insert into address...语句,再执行一条insert into persons...语句。换一个方向来说,如果上面的映射文件缺少cascade="all",则程序运行到③处将抛出TransientObjectException异常。

必须牢记:要么总是先持久化主表记录对应的实体,要么设置级联操作否则当hibernate试图插入从表记录时,如果发现该从表记录参照的主表记录不存在,就会抛出异常。

运行Test.java,查看数据库:

你可能感兴趣的文章
facebook人脸照片_如何阻止Facebook在别人的照片中建议您的名字
查看>>
如何在离开时自动检测巢穴
查看>>
ubuntu显示管理器_如何在Ubuntu的文件管理器中显示导航栏而不显示面包屑
查看>>
关于极客
查看>>
谷歌地图位置偏移_如何使用Google地图与他人临时分享您的位置
查看>>
自定义日历_如何在网络上自定义Google日历的通知
查看>>
hue功能_Philips Hue的“新实验室”部分中的最佳实验功能
查看>>
微软office在线文档_如何使用Microsoft Office密码保护文档和PDF
查看>>
如何在SHIELD Android TV上调整过扫描
查看>>
outlook 禁用不安全_如何在Outlook中禁用删除确认对话框
查看>>
应用程序白名单实现_如何在Windows 10上仅允许商店中的应用程序(和白名单桌面应用程序)...
查看>>
找到丢失的磁贴跟踪器后如何获取通知
查看>>
PlayStation 4 Pro上的“升压模式”是什么?
查看>>
android 更改软键盘_如何在Android上更改Google键盘的主题
查看>>
kodi 缓存文件夹_如何将Kodi图稿与视频存储在同一文件夹中
查看>>
windows隐藏磁盘_如何在Windows的磁盘清理工具中启用隐藏选项
查看>>
如何在Linux或macOS终端中使用Bash历史记录
查看>>
photos设置成中文_如何在OS X的Photos中设置和使用扩展程序
查看>>
大剧院自助签证_如果您的项目是《剧院》,请使用演员
查看>>
qnx 开发十步_十步实现应用程序本地化
查看>>