精通Hibernate——级联操纵对象

当我们加载一个类时session会加载所有和该类直接关联或者间接关联的对象。

在对象关系映射文件中,用于映射持久化类之间关联关系的元素,如、和元素,都有一个cascade属性,他用于指定如何操纵与当前关联的对象,他的可选属性如下:

none:在保存、更新或删除对象时,忽略其他关联的对象,他是cascade默认属性

save-update:当通过session的save、update以及saveOrUpdate方法来保存或更新当前对象时,级联保存所有关联的新建的临时对象,并且级联更新所有关联的游离对象

delete:当通过session的delete方法删除当前对象时,级联删除所有关联的对象

all:包含save-update以及delete行为以外,对当前对象执行evict或lock操作时,也会对所关联的持久化对象执行evict或lock操作

delete-orphan:删除所有和当前对象解除关联关系的对象

all-delete-orphan:包含all和delete-orphan行为

我们以下面类的关系为例:

1、级联保存临时对象

saveFoodCategory()方法先创建三个Category临时对象,建立他们之间的关联关系,然后调用saveOrUpdate方法保存foodCategory对象。

public void saveFoodCategory() throws Exception{
    Category foodCategory = new Category("food",null,new Hashset());
    Category fruitCategory = new Category("fruit",null,new Hashset());
    Category appleCategory = new Category("apple",null,new Hashset());
    // 建立食品类别和水果类别之间的关系
    foodCategory.addChildCategory(fruitCategory);
    // 建立水果类别和苹果类别之间的关系
    fruitCategory.addChildCategory(appleCategory);
    saveOrUpdate(foodCategory);
}

saveOrUpdate方法调用session的saveOrUpdate方法来保存foodCategory对象。执行步骤如下:

1.由于foodCatogory为临时对象,因此session调用save方法来保存foodCategory对象

2.session通过foodCategory.getChildCategories方法导航到fruitCategory临时对象,调用save方法来保存fruitCategroy临时对象

3.session通过fruitCategory.getChildCategories方法导航到appleCategory临对象,调用save方法来保存appleCategory临时对象

Session在清理缓存的时候执行三条insert语句

insert into categories (name,category_id,id) values("food",null,1);
insert into categories (name,category_id,id) values("fruit",1,2);
insert into categories (name,category_id,id) values("food",2,3);

2、更新持久化对象

saveOrangeCategory()方法用于持久化一个orangeCategory对象,他会先调用findCategoryByName(session,”fruit”)方法,由于该查询方法与saveOrangeCategory()方法公用一个session,因此,他返回的fruitCategory对象处于持久化状态。接下来创建一个orangeCategory临时对象,建立fruitCategory与orangeCategory之间的关联关系。

3、持久化临时对象

saveVegetableCategory()方法用于持久化一个vegetableCategory临时对象

saveVegetableCategory()方法先调用findCategoryByName(“food”)方法,该方法不与saveVegetableCategory()方法公用一个session,因此返回的foodCategory对象处于游离状态。接下来创建一个vegetableCategory临时对象,建立foodCategory与vegetableCategory之间的关联关系。最后调用saveOrUpdate()保存vegetableCategory对象:

public void saveVegetableCategory() throws Exception{
    // 返回的foodCategory是游离对象
    Category foodCategory = findCategoryByName("food");
    Category vegetableCategory = new Category("vegetable",null,new HashSet());
    // foodCategory游离对象与vegetableCategory临时对象关联
    foodCategory.addChildCategory(vegetableCategory);
    saveOrUpdate(vegetableCategory);
}

saveOrUpdate方法调用Session的saveOrUpdate来保存vegetableCategory对象,Session的saveOrUpdate执行以下步骤:

1.由于vegetableCategory为临时对象,因此Session调用save方法持久化vegetableCategory对象。

2.Session通过vegetableCategory.getParentCategory()方法导航到foodCategory对象,由于foodCategory对象为游离对象,因此调用update方法更新foodCategory对象。

3.Session通过foodCategory.getChildCategories方法导航到fruitCategory对象,由于fruitCategory对象为游离对象,因此调用update方法更新fruitCategory对象

4、更新游离对象

updateVegetableCategory方法用于更新vegetableCategory对象的name属性,并且创建一个tomatoCategory对象,他与vegetableCategory对象关联

updateVegetableCategory方法先调用findCategoryByName(“vegetable”)方法,该查询方法不与updateVegetableCategory方法公用一个Session,因此返回的vegetableCategory对象处于游离状态。接下来修改vegetableCategory对象的name属性,然后创建一个tomatoCategory临时对象,建立vegetableCategory与tomatoCategory之间的关联关系,最后调用saveOrUpdate方法封信vegetableCategory对象

public void updateVegetableCategory() throws Exception{
    //返回的vegetableCategory是游离对象
    Category vegetableCategory = findCategoryByName("vegetable");
    vegetableCategory.setName("green vegetable");
    Category tomatoCategory = new Category("tomato",null,new HashSet());
    //vegetableCategory游离对象与tomato临时对象关联
    vegetableCategory.addChildCategory(tomatoCategory);
    saveOrUpdate(vegetableCategory);
}

5、遍历对象图

navigateCategories方法先调用findCategoryByName(“fruit”)方法,由于该查询方法不与navegateCategories公用一个Session,因此他返回的fruitCategory对象处于游离状态。接下来调用navigateCategories(fruitCategory,categories)取得所有关联的Category游离对象

   public void navigateCategores() throws Exception{
    Category fruitCategory = findCategoryByName("fruit");
    HashSet categories = new HashSet();
    navigateCategories(fruitCategory,categories);
    //打印categories集合中所有的Category对象
    for(Iterator it = categories.iterator();it.hasNext();){
        System.out.println(((Category)it.next()).getName());
    }
}

navigateCategories方法利用递归算法,遍历所有与fruitCategory关联的父类别及类别Category对象,把他们存放在一个Set集合中:

private void navigateCategories(Category category,Set categories){
    if(categories.contains(category) || category == null) return;
    categories.add(category);
    //递归遍历父类Category
    navigateCategories(category.getParentCategory(),categories);
    Set childCategories = category.getChildCategores();
    if(childCategories == null) return;
    //递归遍历所有子类Category
    for(Iterator it = childCategores.interator();it.hasNext();){
        navigateCategories((Category)it.next(),categories);
    }
}
时间: 2024-10-25 07:21:54

精通Hibernate——级联操纵对象的相关文章

《精通Hibernate:Java对象持久化技术详解》目录

图书信息:孙卫琴 电子工业出版社 第1章 Java应用分层架构及软件模型: 1.1 应用程序的分层体系结构 1.1.1 区分物理层和逻辑层 1.1.2 软件层的特征 1.1.3 软件分层的优点 1.1.4 软件分层的缺点 1.1.5 Java应用的持久化层 1.2 软件的模型 1.2.1 概念模型 1.2.2 关系数据模型 1.2.3 域模型 1.2.4 域对象 1.2.5 域对象之间的关系 1.2.6 域对象的持久化概念 1.3 小结 1.4 思考题第2章 Java对象持久化技术概述: 2.1

攻城狮在路上(壹) Hibernate(六)--- 通过Hibernate操纵对象(上)

一.Hibernate缓存简介: Session接口是Hibernate向应用程序提供的操纵数据接口的最主要接口,它提供了基本的保存.更新.删除和加载Java对象的方法. Session具有一个缓存,位于缓存中的对象称为持久化对象,Session能够在某些时间点来同步更新数据库,这一过程即为清理缓存. Hibernate把对象分为4种状态:持久化状态.临时状态.游离状态和删除状态. 二.Session的缓存: Session的缓存由一系列Java集合构成的. 1.Session缓存的作用: A.

Hibernate利用关联关系操纵对象

利用关联关系操纵对象 数据对象之间关联关系有一对一.一对多及多对多关联关系.在数据库操作中,数据对象之间的关联关系使用JDBC处理很困难.本节讲解如何在Hibernate中处理这些对象之间的关联关系.本节使用到4个类,它们分别是Student(学生).Card(学生证).Group(班级)和Course(课程),它们之间的关联关系如图1-1所示.这些实体存在级联(cascade)问题.例如,当删除一个班级的信息时,还要删除该班的所有学生的基本信息.如果直接使用JDBC执行这种级联操作,会非常烦琐

攻城狮在路上(壹) Hibernate(七)--- 通过Hibernate操纵对象(下)

一.与触发器协同工作: 当Hibernate与数据库的触发器协同工作时,会出现以下两类问题: 1.触发器使Session缓存中的数据和数据库中的不一致: 出现此问题的原因是触发器运行在数据库内,它执行的操作对Session是透明的. 解决方案:在执行完包含有触发器的操作之后,立刻调用Session的flush()和refresh()方法,迫使Session的缓存与数据库同步. 2.Session的update()方法盲目的激发触发器: 这种情况主要发生在Session调用update()或sav

精通Hibernate——建立单向多对一关联

在类与类之间各种各样的关系中,要算多对一的单向关联关系和关系数据库中的外键参照关系最匹配了.因此,通常选择从Order到Customer的多对一单向关联.简要代码如下: public class Customer implements Serializable{ private Long id; private String name; .... } public class Order implements Serializable{ private Long id; private Stri

Hibernate(二)——POJO对象的操作

POJO对象其实就是我们的实体,这篇博客总结一下框架对POJO对象对应数据库主键的生成策略,和一些对POJO对象的简单增删改查的操作.  一,Hibernate框架中主键的生成策略有三种方式: 1,数据库负责生成主键(代理主键)  a,native:表示由设置的方言决定采用什么数据库生成主键方式,例如:在MySQL中会采用自增长的方式,主键字段必须都是整形类型:在Oracle数据库中,会采用序列的增长方式.  b,sequence:表示采用数据库的序列生成主键,适用于Oracle,DB2数据库中

ORM进阶之Hibernate 的三大对象

ORM进阶之 ORM简介 ORM进阶之Hibernate 简介及框架搭 ORM进阶之Hibernate 的三大对象 我们在上一篇博客中讲到了如何搭建一个Hibernate框架, 提到Hibernate我们就不得不说他的三大对象,Configuration,SessionFactory , Session .下边我们就分别来解释一下这三大对象! Configuration对象 Configuration类用来管理我们的配置文件的信息的,通过它,我们可以通过创建一个configuration实例来管

hibernate中持久化对象的生命周期(三态:自由态,持久态,游离态 之间的转换)

三态的基本概念: 1,  暂时状态(Transient):也叫自由态,仅仅存在于内存中,而在数据库中没有对应数据.用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫暂时对象: 2,  持久化状态(Persistent):与session关联而且在数据库中有对应数据.已经持久化,添?到了Session缓存中.如通过hibernate语句保存的对象.处于此状态的对象叫持久对象: 3,  游离状态(Detached):持久化对象脱离了Session的对象.如Session缓

hibernate级联保存,更新个人遇到的问题

在级联更新的时候,数据库中的数据是增加的,只是外键不存在,导致这样的问题产生的原因是,字表主键ID没有添加到集合中,导致Hibernate找不到子项而执行更新. hibernate级联保存,更新个人遇到的问题,布布扣,bubuko.com