一、单向多对一关联关系

  一)、使用LocalSessionFactoryBean类,即在applicationContext中配置的

<!-- 配置SessionFactory 使用LocalSessionFactoryBean-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="mappingLocations" >
<list>
<value>classpath:com/zcd/hibernate/manyToOne/*.hbm.xml</value>
<value>classpath:com/zcd/hibernate/manyToOneBoth/*.hbm.xml</value>
<value>classpath:com/zcd/hibernate/oneToMany/*.hbm.xml</value>
<value>classpath:com/zcd/hibernate/oneToOneForeign/*.hbm.xml</value>
<value>classpath:com/zcd/hibernate/oneToOnePrimary/*.hbm.xml</value>
</list>
</property>
</bean>

    ①、以上配置的这个SessionFactory 类的对象的getCurrentSession()方法获取的Session 对象

      先保存一端再保存多端:正常

      先保存多端再保存一端:异常

    ②、但是如果使用这个对象的openSession() 方法

      先保存一端再保存多端:正常

      先保存多端再保存一端:没有异常,但不能保存外键列

====================================================================

  二)、如果通过以下方式获取的SessionFactory ,我看了一下底层代码,如果没错的话这个SessionFactory 指的是SessionFactoryImpl 这个类。

    private SessionFactory sessionFactory;
private Session session;
private Transaction transaction; @Before
public void init()
{
//创建一个Configuration对象:对应于hibernate的配置信息和对象关系映射
Configuration configuration = new Configuration().configure(); //创建一个ServiceRegistry对象,所有的hibernate配置和服务都要注册到这个对象中才有效
ServiceRegistry serviceRegistry =
new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry(); //创建SessionFactory对象
sessionFactory = configuration.buildSessionFactory(serviceRegistry); //创建Session
session = sessionFactory.openSession();
// session = sessionFactory.getCurrentSession(); //开启事务
transaction = session.beginTransaction();
System.out.println(transaction);
}

    ①、这个SessionFactory 类的对象的getCurrentSession()方法获取的Session对象

      先保存一端再保存多端:异常

      先保存多端再保存一端:异常

    ②、但是如果通过openSession()方法获取的Session对象,

      先保存一端再保存多端:正常

      先保存多端再保存一端:正常, 但是会多出UPDATE语句。

=======================================================================

总结:在保存单向多对一关联关系的对象的时候,最好是先保存一端,再保存多端,这样既可以提高数据库的性能,又可以减少异常的发生。

二、一对一关联关系,基于主键映射。

跟上面的一样两种方式获取不同的SessionFactory 的实现类的实例

  一)、LocalSessionFactoryBean 实现类

    ①、getCurrentSession()方法获取的Session 对象。

      举例子:有Boss 和Company 两个类。Boss类对应的表主键类又做为外键列。

      先保存有外键的一端。

        //设定关联关系
company.setBoss(boss);
boss.setCompany(company); //先保存有外键的一端
oneToOnePrimaryService.saveBoss(boss);
oneToOnePrimaryService.saveCompany(company);

      此时会重复保存两次 Company 对象,个人猜测:可能是因为boss中已经持有了company 的引用,所以在保存boss 的时候也保存了company对象,接着又保存了一次company,所以才会出现保存两次的情况。但是在保存boss对象的时候也是先保存了boss引用的company对象。

      先保存没有外键的一端

        //设定关联关系
company.setBoss(boss);
boss.setCompany(company); //先保存没有外键的一端
oneToOnePrimaryService.saveCompany(company);
oneToOnePrimaryService.saveBoss(boss);

此时先保存company,在保存boss,属于正常,而且company 也不会重复保存。

===================================================================

    ②、如果是使用openSession()方法获取的session对象

      先保存有外键的一端:虽然没有发生异常,但是不能正常保存

  

      先保存没有外键的一端:虽然没有发生异常,但是不能正常保存

  二)、SessionFactoryImpl 实现类获取的

    ①、使用getCurrentSession() 方法获取session对象。 

      先保存有外键的一端: 异常

      先保存没有外键的一端:异常

    ②、使用openSession()方法获取Session对象。

      先保存有外键的一端: 正常保存

      先保存没有外键的一端:正常保存

      而且基于主键映射的使用openSession()方法获取的 Session 保存对象,不论先保存哪一端都不会发送update 语句

---------------------------------------------------------------------------------------------------------------------

总结:所以以后一对一映射最好保存没有外键的一端。

三、一对一关联关系基于外键映射

  跟上面一样的方式获取不同的SessionFactory 的实现类的实例

  一)、LocalSessionFactoryBean 类

    ①、使用getSessionFactory()方法

      先保存有外键的一端:  异常

      先保存没有外键的一端: 正常保存

    ②、使用openSession()方法

      先保存有外键的一端: 不能正常保存,有外键的一端不能正常保存外键列,因为没有发送update语句。

      先保存没有外键的一端: 正常保存,没有update语句

  二)、SessionFactoryImpl 类

    ①、使用getSessionFactory()方法

      先保存有外键的一端:发生异常

      先保存没有外键的一端:发生异常

    ②、使用openSession()方法

      先保存有外键的一端:正常保存,但会发送update语句

      先保存没有外键的一端:正常保存,而且不会发送update语句。

---------------------------------------------------------------------------------------------------------------------------------

总结:在使用一对一关联关系时,保存对象不管使用哪个SessionFactory的实现类的哪个方法获取Session,在保存对象时最好先保存没有外键列的一端。

四、双向多对一关联关系

  一)、LocalSessionFactoryBean 类

    ①、

    ②、

  二)、SessionFactoryImpl 类

    ①、

    ②、

五、双向多对多关联关系

  一)、LocalSessionFactoryBean 类

    ①、

    ②、

  二)、SessionFactoryImpl 类

    ①、

    ②、

关于SessionFactory的不同实现类分别通过getCurrentSession()方法 和 openSession() 方法获取的Session对象在保存对象时的一些区别的更多相关文章

  1. 简述JavaScript对象、数组对象与类数组对象

    问题引出 在上图给出的文档中,用JavaScript获取那个a标签,要用什么办法呢?相信第一反应一定是使用document.getElementsByTagName('a')[0]来获取.同样的,在使 ...

  2. .NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

    开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以, ...

  3. 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间

    [源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...

  4. Android 通过 Intent 传递类对象或list对象

    (转:http://www.cnblogs.com/shaocm/archive/2013/01/08/2851248.html) Android中Intent传递类对象提供了两种方式一种是 通过实现 ...

  5. JOptionPane类提示框的一些常用的方法

    JOptionPane类提示框的一些常用的方法 XMLOracleSwing 最近在做swing程序中遇到使用消息提示框的,JOptionPane类其中封装了很多的方法. 很方便的,于是就简单的整理了 ...

  6. Javascript定义类(class)的三种方法

    将近20年前,Javascript诞生的时候,只是一种简单的网页脚本语言.如果你忘了填写用户名,它就跳出一个警告. 如今,它变得几乎无所不能,从前端到后端,有着各种匪夷所思的用途.程序员用它完成越来越 ...

  7. zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法

    转载自:http://blog.csdn.net/wide288/article/details/21622183 zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法: ze ...

  8. 转载:java 中对类中的属性使用set/get方法的意义和用法

    经常看到有朋友提到类似:对类中的属性使用set/get方法的作用?理论的回答当然是封闭性之类的,但是这样对我们有什么作用呢?为什么要这样设计?我直接使用属性名来访问不是更直接,代码更简洁明了吗?下面我 ...

  9. 监听器和普通类获取springContext和context,从而获取springbean和application范围的对象

    1.定义一个监听器[MyContextListener],此类里最主要获取springContext和context package my.request; import javax.servlet. ...

随机推荐

  1. poj3176

    一.题意:给定一些数,成三角形排列.从上往下走,每个数只能往它相邻的两个数走,一直走到底端得到一条线路.这条线路上的数的和最大是多少 二.思路:简单的动态规划.dp[i+1][j+1]:=以第i+1行 ...

  2. PIE SDK栅格拉伸控制

    1. 功能简介 在我们的实际应用中,对于一般16bit或者更大比特深度的影像,像元值都是大于255的.这种情况下,RGB的显示器是不能够直接使用像元值进行显示的,需要将像元值换算到0~255的区间内以 ...

  3. easyUI--datagrid 实现按键控制( enter tab 方向键 )

    1.表格定义时加上 onClickCell: onClickCell,2.定义列时加入编辑器3.引入 key.js 即可使用 enter 键 或者向下箭头 选中单元格下移 选中单元格上移 tab键 选 ...

  4. Angular4+NodeJs+MySQL 入门-03 后台接口定义

    这篇里是如何定义接口,我们一般访问接口如:post请求调用http://127.0.0.1:11000/webapi/userinfo/user 这个接口,成功返回用户信息,如果失败要返回失败原因等. ...

  5. Git~GitLab当它是一个源代码管理工具时

    最近开始接触和使用GitLab,用它来做源代码的版本控制,CI.CD持续集成和持续交付,感觉功能确实很强大,今天也只能先说一下它的源代码管理功能,核心就是GIT,对GIT进行了封装,提供了一些扩展功能 ...

  6. 【数据结构】最小生成树之prim算法和kruskal算法

    在日常生活中解决问题经常需要考虑最优的问题,而最小生成树就是其中的一种.看了很多博客,先总结如下,只需要您20分钟的时间,就能完全理解. 比如:有四个村庄要修四条路,让村子能两两联系起来,这时就有最优 ...

  7. bzoj 5314: [Jsoi2018]潜入行动

    Description 外星人又双叒叕要攻打地球了,外星母舰已经向地球航行!这一次,JYY已经联系好了黄金舰队,打算联合所有JSO Ier抵御外星人的进攻.在黄金舰队就位之前,JYY打算事先了解外星人 ...

  8. 【VMware】无法连接MKS:套接字连接尝试次数太多;正在放弃

    启动我的电脑 -> 右键 -> 管理 -> 服务和应用程序 -> 服务: 将当前服务全部进行启动

  9. 如何设计一个“高大上”的 logo

    前不久,我们老大写的一篇博客< Coding,做一个有情怀的产品 >中有提到设计 Coding logo 的大致由来,今天我就设计 Coding 猴头的过程具体说说如何设计一个 logo. ...

  10. WAMP环境配置-Mysql安装

    1.下载并解压MySQL5.6.36压缩包(顺便重命名一下子). 2.将my-default.ini文件复制一份改名为my.ini,然后修改下面红框标注的地方 3.安装与启动服务. 以管理员的身份运行 ...