zoukankan      html  css  js  c++  java
  • Hibernate unsaved-value 属性

    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

  • 相关阅读:
    sicp-py
    Ubuntu下找不到ttyUSB*问题解决
    Mysql基本命令及数据库存储位置
    open-vm-tools与VMware Tools
    64位ubuntu安装交叉编译工具链,显示找不到命令
    VMware Tools 继续运行脚本未能在虚拟机中成功运行。
    VMware Workstation 14安装VMware Tools
    VMware Workstation14 安装Ubuntu18.04
    Linux安装Sqlite
    mysql中文乱码
  • 原文地址:https://www.cnblogs.com/langtianya/p/4721694.html
Copyright © 2011-2022 走看看