Session的saveOrUpdate方法是由Hibernate来判断被操作对象究竟是一个持久化对象还是临时自由状态对象。这需要在对象映射文件的主键id中定义unsaved-value属性,如果不显式定义,则默认为unsaved-value=null。

unsaved-value可以是下列几个选项: 
1)null:主键是对象类型,Hibernate判断操作对象的主键是否为null,来判断操作对象是否以被持久化,如果是,调用save方法,生成insert语句,在数据库中增加一条记录,如果不是,设置主键则直接生成update的SQL语句,发送update,如果数据库中没有那条记录则抛出异常。 
2)none:由于不论主键属性为任何值,都不可能为none,因此Hibernate总是对被操作对象发送update。 
3)any:由于不论主键属性为任何值,都肯定为any,因此Hibernate总是对被操作对象发送save,Hibernate生成主键。

显式的使用session.save()或者session.update操作一个对象时,实际上市用不到unsaved-value的。

在一个session中,持久化对象的变化,不需要调用update等显式语句,由flush方法就可以实现数据库表的更新。

不同session之间的对象,也就是游离状态的对象,必须使用update显式更新数据库表。

修改一个对象,最好的方法是使用session的load方法进行持久化,然后使用set方法实现属性的修改,一般情况下,不要使用setId方法来修改对象的主键值,避免产生意想不到的错误。

使用Hibernate的id generator来生成无业务意义的主键,不使用有业务含义的字段作主键,不建议使用assigned。

使用对象类型(String/Integer/Long/...)来做主键,而不使用基础类型(int/long/...)做主键

01-03-01【Nhibernate (版本3.3.1.4000) 出入江湖】id标签的unsaved-value属性

 

父表

  <class name="Model.Customer, Model"
discriminator-value="0">
<!--unsaved-value="0" 主键表中不需要定义,而是需要在子表中定义-->
<id name="CustomerId"
column="CustomerId"
type="Int32"
unsaved-value="0">
<generator class="native" />
<!-- unsaved-value used to be null and generator was increment in h2.0.3 -->
</id>

子表

  <class name="Model.Order, Model"
table ="[Order]"
discriminator-value="0" lazy="false">
<id name="OrderId"
column="OrderId"
type="Int32"
unsaved-value="0">
<generator class="native" />
<!-- unsaved-value used to be null and generator was increment in h2.0.3 -->
</id>
了解unsaved-value,需要知道如下知识点:

1.unsaved-value默认值是null
2.id的type标签属性可以标示为:
【1】基本对象类型如int,long
【2】对象类型,如Int32,Int64 3.Nhibernate保存机制:
当父对象调用save(),由于级联的关系,保存子对象,那么保存子对象的方式
到底是Upadate(已经持久化在数据库中)
还是Save(还没有持久化在数据库中,只是刚刚在内存中新new)? 如何判断是用调用upadte还是调用Save,
答案是:
用unsaved-value的值与HNibernate自动从数据库中获取的子类对象的Id进行比较,
   (注意:如果没有持久化,HNibernate自动从数据库中获取的子类对象的Id的值等于null)
  如果是:
  【1】unsaved-value的值与子类对象的Id相等,表明没有持久化,调用save;
  【2】unsaved-value的值与子类对象的Id不相等,表明已持久化,调用Update;

    综上,
当子表id标签的type标签属性标示为:
【1】基本对象类型如int,long,需要显示明unsaved-value = 0,因为unsaved-value默认值是null,而基本对象类型如int的默认值为0,
这样使得即使子类对象还没有持久化,HNibernate自动从数据库中获取的子类对象的Id=0,
这样根据上述的Nhibernate保存机制,永远调用Upadte,不会调用save。 
    <id name="OrderId"
column="OrderId"
type="Int"
unsaved-value="0">
  【2】对象类型,如Int32,Int64,不需要
    <id name="OrderId"
column="OrderId"
type="Int32" >

http://www.cnblogs.com/easy5weikai/p/3746322.html

Hibernate unsaved-value 属性的更多相关文章

  1. Hibernate的generator属性之意义

    Hibernate的generator属性之意义 本文讲述Hibernate的generator属性的意义.Generator属性有7种class,本文简略描述了这7种class的意义和用法. Hib ...

  2. Hibernate中inverse属性与cascade属性

    Hibernate集合映射中,经常会使用到"inverse"和"cascade"这两个属性.对于我这样,Hibernate接触不深和语文水平够烂的种种因素,发现 ...

  3. Hibernate的generator属性

    本文讲述Hibernate的generator属性的意义.Generator属性有7种class,本文简略描述了这7种class的意义和用法. <class name="onlyfun ...

  4. Hibernate 中配置属性详解(hibernate.properties)

    Hibernate能在各种不同环境下工作而设计的, 因此存在着大量的配置参数.多数配置参数都 有比较直观的默认值, 并有随 Hibernate一同分发的配置样例hibernate.properties ...

  5. Hibernate映射Map属性

    看到一篇Hibernate 映射Map属性的文章挺好的转载一下原地址:http://blog.sina.com.cn/s/blog_86f4502c0101fs1x.html Map集合属于有序集合, ...

  6. HIbernate的property-ref属性

    为公司之前的一个公交卡系统修改bug: 通过排查发现, 卡类型表和卡等级表是一对多的关系, 但是卡等级表中没有字段引用卡类型表的主键,而是引用了卡类型表中非主键的另外两个字段 通过查看hibernat ...

  7. Hibernate持久化类属性映射

    Hibernate充当应用程序和数据库之间的中间件,实现二者之间的交互操作,他对JDBC进行了封装,以完全面向对象的方式来操作数据. 适用于有多个数据源的情况下,不必去考虑不同数据源的操作差异. Hi ...

  8. 。。。Hibernate中mappedBy属性。。。

    今天在学习Hibernate中,感觉这个mappedBy这个注解属性有点小难度.不过理解之后,还是阔以的! 首先,mappedBy这个注解只能够用在@OntToOne,@OneToMany,@many ...

  9. Hibernate设置派生属性(formula)

    一.Customer中包含的字段: private static final long serialVersionUID = 1L;    private Integer id;    private ...

  10. Hibernate映射集合属性

    Hibernate要求持久化集合属性字段必须声明为接口,实际的接口可以是java.util.Set,java.util.Collection,java.util.List,java.util.Map, ...

随机推荐

  1. An Introduction to Interactive Programming in Python (Part 1) -- Week 2_2 练习

    #Practice Exercises for Logic and Conditionals # Solve each of the practice exercises below. # 1.Wri ...

  2. Matlab中reshape函数的使用

    reshape把指定的矩阵改变形状,但是元素个数不变, 例如,行向量: a = [1 2 3 4 5 6] 执行下面语句把它变成3行2列: b = reshape(a,3,2) 执行结果: b = 1 ...

  3. Eclipse系列:如何断点调试web项目

    一直不知道如何在Eclipse中断点调试跟踪问题,今天试了一把,大致的步骤如下: 1)事先在需要断点跟踪的代码行左侧空白处双击处设置断点: 2)在工程列表中选中要调试的工程,然后点击Debug on ...

  4. Linux 第一次学习笔记

    一.Linux 为何物 Linux 就是一个操作系统,就像你多少已经了解的 Windows(xp,7,8)和 Max OS ,至于操作系统是什么,就不用过多解释了,如果你学习过前面的入门课程,应该会有 ...

  5. [C/C++基础] C语言常用函数strlen的使用方法

    函数声明:extern unsigned int strlen(char *s); 所属函数库:<string.h> 功能:返回s所指的字符串的长度,其中字符串必须以’\0’结尾 参数:s ...

  6. express 笔记 app.helpers 和 app.locals

    app.helpers 和app.dynamicHelpers 是express2.X使用的 分别为静态/动态 视图助手通过其注册函数, 例如 app.helpers({ <span style ...

  7. linux之条件判断

    一.文件类型比较 判断一个文件是否存在(注意:中括号表示判断,其两边必须有空格) 二.文件权限判断 判断是否有可执行权限(这里是不区分用户的,只要该文件能执行就返回0) 3.整数比较 判断两个数是否相 ...

  8. 第三章:javascript: 列表

    在日常生活中,人们经常使用列表:待办事项列表,购物清单,十佳榜单,最后十名榜单等.计算机也在使用列表,尤其是列表中元素保存的是太多时.当不需要一个很长的序列中查找元素,或对其进行排序时,列表显得尤为有 ...

  9. SDAutolayout图片大小根据数量变化

    只需要在自定义的PhotoContainerView中做一下判断就可以了 ) { [self setupAutoWidthFlowItems:[temp copy] withPerRowItemsCo ...

  10. 软工实践练习——使用Git进行代码管理

    GITHUB上的预备活动: 注册 创建小组Organization,邀请组员进来 将代码库fork到小组Organization底下 下载并使用GIT: Git的安装 使用Git进行代码管理 1.从百 ...