`

Hibernate-unsaved

 
阅读更多

unsaved-value----à主要是给Hibernate在程序没有显示调用save 或者 update判断使用的?====è不是的,它应该是在Hibernate在清除缓存也就是刷新缓存时,会根据unsaved-value和缓存中的实体对象的id值进行比较,如果id同为null值则采取insert的操作,如果值不一样则使用update sql操作。
    以上是""方的重要配置,再看看""方的一个重要配置:unsaved-value,就像上面Product.hbm.xml中的设置那样,这一项在id的配置中设置。这一设置是与级联一起工作的。关于这一点,robbin讲的很清楚:
你显式的使用session.save()或者session.update()操作一个对象的时候,实际上是用不到unsaved-value 的。某些情况下(父子表关联保存),当你在程序中并没有显式的使用save或者update一个持久对象,那么Hibernate需要判断被操作的对象究竟是一个已经持久化过的持久对象,是一个尚未被持久化过的内存临时对象。例如:

       Session session = ...;  

  1. Transaction tx = ...;  
  2. Parent parent = (Parent) session.load(Parent.class, id);  
  3. Child child = new Child();  
  4. child.setParent(parent);  
  5. child.setName("sun");  
  6. parent.addChild(child);  
  7. s.update(parent);  
  8. s.flush();  
  9. tx.commit();  
  10. s.close();  

     在上例中,程序并没有显式的session.save(child); 那么Hibernate需要知道child究竟是一个临时对象,还是已经在数据库中有的持久对象。如果child是一个新创建的临时对象(本例中就是这种情况),那么Hibernate应该自动产生session.save(child)这样的操作,如果child是已经在数据库中有的持久对象,那么 Hibernate应该自动产生session.update(child)这样的操作。因此我们需要暗示一下Hibernate,究竟 child对象应该对它自动save还是update。在上例中,显然我们应该暗示Hibernatechild自动save,而不是自动 update。那么Hibernate如何判断究竟对childsave还是update呢?它会取一下child的主键属性 child.getId() ,这里假设id java.lang.Integer类型的。如果取到的Id值和hbm映射文件中指定的unsave-value相等,那么Hibernate认为 child是新的内存临时对象发送save,如果不相等,那么Hibernate认为child是已经持久过的对象,发送update unsaved-value="null" (默认情况,适用于大多数对象类型主键 Integer/Long/String/...)
Hibernate取一下childId,取出来的是null(在上例中肯定取出来的是null),和unsaved-value设定值相等,发送save(child)
Hibernate取一下childid,取出来的不是null,那么和unsaved-value设定值不相等,发送update(child)
   unsaved-value
的可选配置有:
none
anynull
unsaved- value="none"
unsaved-value="any"主要用在主键属性不是通过Hibernate生成,而是程序自己setId()的时候。unsaved-value="none"unsaved-value="any"究竟有什么含义了。如果你非要用assigned不可,那么继续解释一下:
unsaved-value="none"
的时候,由于不论主键属性为任何值,都不可能为none,因此Hibernate总是对child对象发送update(child)
unsaved-value="any"
的时候,由于不论主键属性为任何值,都肯定为any,因此Hibernate总是对child对象发送save(child)

     
大多数情况下,可以避免使用assigned,只有当你使用复合主键的时候不得不手工setId(),这时候需要你自己考虑究竟怎么设置unsaved-value了,根据你自己的需要来定。
     
关于为什么不要使主键带有义务意义,robbin的解释很清楚:还是以上面的例子打比方,如果我们将Category的某一个性质(比如产品序号或者名称)作为主键,如果后来由于业务需要,我们把这个性质改了,那将不可僻免地要去修改与这个对象相关联的所有数据的外键,而如果我们只要代理主键,这个问题就可完全僻免

分享到:
评论

相关推荐

    hibernate-mapping参数详解

    5. `unsaved-value`:这个属性用于标记新创建且尚未保存的实例。它的值通常是某个字段的特殊值,用于区分已保存和未保存的实例。 6. `access`:与`default-access`类似,`access`参数也定义了访问对象属性的策略,...

    Hibernate入门 - 基础配置

    <id name="id" unsaved-value="0"> <property name="name" not-null="true"/> <loader query-ref="person"/> <sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert> <sql-update...

    hibernate配置详解

    <id name="id" type="string" unsaved-value="null"> <column name="cat_id" sql-type="varchar(20)" not-null="true"/> <column name="NAME" sql-type="varchar(20)" not-null="true"/> </...

    hibernate配置元素例子.txt

    - **`unsaved-value`属性**:未保存状态的值,此处设置为`null`表示当实体处于未保存状态时,该字段的值为`null`。 - **`generator`子元素**:定义主键的生成策略,这里采用`uuid.hex`,意味着使用基于UUID的十六...

    hibernate一对多例子

    <id name="sid" type="string" unsaved-value="null"> <column name="sid" sql-type="char(32)" not-null="true"/> <column name="sname" sql-type="varchar(16)" not-null="true"/> ...

    Hibernate O R映射三大基本定则

    <id name="id" column="id" type="long" unsaved-value="any"> ``` 在这个例子中,User类可以有更多如`email`、`password`等属性,但`name`和`login`属性必须在类中存在,因为它们已经在映射文件中...

    Hibernate主键类型说明和配置手册.doc

    <id name="id" unsaved-value="null"> ``` 2. **sequence**: 此策略适用于支持序列的数据库,如Oracle。你需要指定一个序列名,如下所示: ```xml <id name="id" unsaved-value="0"> ...

    基于Struts+Hibernate+Spring的Web_应用开发

    <id name="id" column="id" type="long" unsaved-value="any"> ``` - **应用场景**:这有助于确保实体类与其对应的数据库表之间的映射一致性。当实体类需要扩展额外属性时,只需在实体类中添加即可,无需...

    Hibernate version 乐观锁 (xml方式)

    在这个配置中,`<version>`标签用于声明乐观锁的版本字段,`column`属性指定数据库对应的列名,`unsaved-value`属性表示未保存的初始值。 在实际的业务逻辑中,当我们试图更新一个用户时,Hibernate会在更新SQL语句...

    Hibernate_DEV_GUIDE

    - **关于unsaved-value**:这是Hibernate中的一种特殊属性设置,用于标识某个属性在对象未保存前的默认值。 - **Inverse和Cascade**:用于控制关联关系中对象的级联操作。 - **延迟加载(LazyLoading)**:这是一种...

    最经典的hibernate教程

    - `unsaved-value`: 未保存的值。 - `access`: 访问策略。 - **<generator> 元素**: 定义主键的生成策略。 - `class`: 生成器类名。 **3.3 <property> 元素** - 用于映射 Java 类中的属性到数据库表中的列。 -...

    夏昕-Hibernate+开发指南.pdf

    - **数据访问**:探讨了PO(Plain Old Java Object)和VO(Value Object)的区别,以及unsaved-value、Inverse和Cascade、延迟加载等概念。 - **事务管理**:介绍了基于JDBC和JTA的事务处理方法。 - **锁机制**:讲解...

    Hibernate开发指南

    - **unsaved-value**: Hibernate中的一种特殊值,用于标识未保存的对象状态。 ##### 9. 事务管理 - **基于JDBC的事务管理**: - 使用Connection对象的commit()和rollback()方法控制事务。 - **基于JTA的事务管理**...

    Hibernate 开发学习指导书

    - **关于unsaved-value**: Hibernate的一个特性,用于标记尚未保存到数据库中的值。 - **Inverse和Cascade**: 用于控制关联关系的更新和级联操作。 - **延迟加载** (Lazy Loading): 一种优化技术,仅在真正需要时才...

    hibernate3.2中文文档(chm格式)

    21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 23.1. Employer(雇主)/...

    HibernateAPI中文版.chm

    21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 23.1. Employer(雇主)/...

    hibernate映射文件的详解

    如果对象的标识属性值等于`unsaved-value`,Hibernate会认为该实例是新创建的,需要执行`save`操作;否则,执行`update`操作。 4. 主键生成器(Key Generator):用于决定如何生成对象的唯一标识(主键)。`...

Global site tag (gtag.js) - Google Analytics