当前位置: 首页 > news >正文

【转】关于Hibernate的unsaved-value

unsaved-value是表示一个对象是新的还是旧的,当显式的使用session.save()或者session.update()操作一个对象的时候,实际上是用不到unsaved-value的。某些情况下(父子表关联保存),当你在程序中并没有显式的使用save或者update一个持久对象,那么Hibernate需要判断被操作的对象究竟是一个已经持久化过的持久对象,是一个尚未被持久化过的内存临时对象。例如:

CODE:    
Session session 
=  ;    
Transaction tx 
=  ;    
Parent parent 
=  (Parent) session.load(Parent. class , id);    
Child child 
=   new  Child();    
child.setParent(parent);    
child.setName(
" sun " );    
parent.addChild(child);    
s.update(parent);    
s.flush();    
tx.commit();    
s.close();

 

在上例中,程序并没有显式的session.save(child); 那么Hibernate需要知道child究竟是一个临时对象,还是已经在数据库中有的持久对象。如果child是一个新创建的临时对象(本例中就是这种情况),那么Hibernate应该自动产生session.save(child)这样的操作,如果child是已经在数据库中有的持久对象,那么Hibernate应该自动产生session.update(child)这样的操作。3^)N%Q(}z1U        Q$x
因此我们需要暗示一下Hibernate,究竟child对象应该对它自动save还是update。在上例中,显然我们应该暗示Hibernate对child自动save,而不是自动update。那么Hibernate如何判断究竟对child是save还是update呢?它会取一下child的主键属性 child.getId() ,这里假设id是 java.lang.Integer类型的。如果取到的Id值和hbm映射文件中指定的unsave-value相等,那么Hibernate认为child是新的内存临时对象,发送save,如果不相等,那么Hibernate认为child是已经持久过的对象,发送update。`_/Zw
mV-yWr

unsaved-value="null" (默认情况,适用于大多数对象类型主键 Integer/Long/String/...)
当Hibernate取一下child的Id,取出来的是null(在上例中肯定取出来的是null),和unsaved-value设定值相等,发送save(child)
当Hibernate取一下child的id,取出来的不是null,那么和unsaved-value设定值不相等,发送update(child)
例如下面的情况:

CODE:    
Session session 
=  ;    
Transaction tx 
=  ;    
Parent parent 
=  (Parent) session.load(Parent. class , id);    
Child child 
=  (Child) session.load(Child. class , childId);    
child.setParent(parent);    
child.setName(
" sun " );    
parent.addChild(child);    
s.update(parent);    
s.flush();    
tx.commit();    
s.close();


child已经在数据库中有了,是一个持久化的对象,不是新创建的,因此我们希望Hibernate发送update(child),在该例中,Hibernate取一下child.getId(),和unsave-value指定的null比对一下,发现不相等,那么发送update(child)。
BTW: parent对象不需要操心,因为程序显式的对parent有load操作和update的操作,不需要Hibernate自己来判断究竟是save还是update了。我们要注意的只是child对象的操作。另外unsaved-value是定义在Child类的主键属性中的。

CODE:    
< class  name ="Child"  table ="child" >     
"id" name="id" type="integer" unsaved-value="null">    
  class="identity"/>    
   
    
class>

如果主键属性不是对象型,而是基本类型,如int/long/double/...,那么你需要指定一个数值型的unsaved-value
例如:

CODE:
unsaved- null="0"


在此提醒大家,很多人以为对主键属性定义为int/long,比定义为Integer/Long运行效率来得高,认为基本类型不需要进行对象的封装和解构操作,因此喜欢把主键定义为int/long的。但实际上,Hibernate内部总是把主键转换为对象型进行操作的,就算你定义为int/long型的,Hibernate内部也要进行一次对象构造操作,返回给你的时候,还要进行解构操作,效率可能反而低也说不定。因此大家一定要扭转一个观点,在Hibernate中,主键属性定义为基本类型,并不能够比定义为对象型效率来的高,而且也多了很多麻烦,因此建议大家使用对象型的Integer/Long定义主键。
unsaved-value="none"和 悠忆社区/V,tq9fs
unsaved-value="any"
主要用在主键属性不是通过Hibernate生成,而是程序自己setId()的时候。www.yoy1.com#m4iCO'n\$T
在这里多说一句,强烈建议使用Hibernate的id generator,或者你可以自己扩展Hibernate的id generator,特别注意不要使用有实际含义的字段当做主键来用!例如用户类User,很多人喜欢用用户登陆名称做为主键,这是一个很不好的习惯,当用户类和其他实体类有关联关系的时候,万一你需要修改用户登陆名称,一改就需要改好几张表中的数据。偶合性太高,而如果你使用无业务意义的id generator,那么修改用户名称,就只修改user表就行了。
由这个问题引申出来,如果你严格按照这个原则来设计数据库,那么你基本上是用不到手工来setId()的,你用Hibernate的id generator就OK了。因此你也不需要了解当社会,体育,生活,情感,搞笑,JAVA技术交流,软件交流,IT资讯(r9j.@%u:s@4k_7P,P
unsaved-value="none"和 社会,体育,生活,情感,搞笑,JAVA,struts,hibernate技术交流,软件交流,IT资讯t;P|_0R+vy,g)z6H
unsaved-value="any"社会,体育,生活,情感,搞笑,JAVA技术交流,软件交流,IT资讯7W'N0W9W'R\
究竟有什么含义了。如果你非要用assigned不可,那么继续解释一下:b i9d e1W[B
unsaved-value="none" 的时候,由于不论主键属性为任何值,都不可能为none,因此Hibernate总是对child对象发送update(child)社会,体育,生活,情感,搞笑,JAVA,struts,hibernate技术交流,软件交流,IT资讯 C5pm
x.o:o

unsaved-value="any" 的时候,由于不论主键属性为任何值,都肯定为any,因此Hibernate总是对child对象发送save(child)社会,体育,生活,情感,搞笑,JAVA技术交流,软件交流,IT资讯G.H#n&WK6WZYWB
大多数情况下,你可以避免使用assigned,只有当你使用复合主键的时候不得不手工setId(),这时候需要你自己考虑究竟怎么设置unsaved-value了,根据你自己的需要来定。
强烈不建议使用composite-id,强烈建议使用UserType。
因此,如果你在系统设计的时候,遵循如下原则:Y?GS*w
OKYw

1、使用Hibernate的id generator来生成无业务意义的主键,不使用有业务含义的字段做主键,不使用assigned。社会,体育,生活,情感,搞笑,JAVA,struts,hibernate技术交流,软件交流,IT资讯:EOs7Z$P"`6h
2、使用对象类型(String/Integer/Long/...)来做主键,而不使用基础类型(int/long/...)做主键社会,体育,生活,情感,搞笑,JAVA,struts,hibernate技术交流,软件交流,IT资讯\MJ%d\b
TI

3、不使用composite-id来处理复合主键的情况,而使用UserType来处理该种情况。
#yo9LLlU a
那么你永远用的是unsaved-value="null" ,不可能用到any/none/..了。

相关文章:

  • 《英雄萨姆2》更新秘籍
  • 添加删除程序中的项目清理
  • JSP 404 ErrorPage 自定义页面处理
  • 某专利信息网存在安全隐患
  • Windows Live Writer 测试一下
  • mdadm
  • Linux下增加Swap区
  • ASP.NET 应用程序生命周期概述
  • 如何计算CPU所需风扇风量
  • XUL
  • JSP学习笔记(八十九):weblogic9.2中设置站点默认页
  • 当下10大最热门的网站开发技术
  • 3.0.22版samba.conf文件配置详细注释
  • 为激情为生---“激情团队宣言”
  • WorkFlow之顺序工作流学习
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • Apache Pulsar 2.1 重磅发布
  • es6(二):字符串的扩展
  • ES6--对象的扩展
  • JavaScript服务器推送技术之 WebSocket
  • javascript面向对象之创建对象
  • java中具有继承关系的类及其对象初始化顺序
  • Js基础知识(一) - 变量
  • mysql 数据库四种事务隔离级别
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Webpack入门之遇到的那些坑,系列示例Demo
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 每天10道Java面试题,跟我走,offer有!
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 如何在GitHub上创建个人博客
  • 时间复杂度与空间复杂度分析
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 最简单的无缝轮播
  • 【云吞铺子】性能抖动剖析(二)
  • #stm32驱动外设模块总结w5500模块
  • #单片机(TB6600驱动42步进电机)
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • ${factoryList }后面有空格不影响
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (4)Elastix图像配准:3D图像
  • (C语言)fread与fwrite详解
  • (floyd+补集) poj 3275
  • (超详细)语音信号处理之特征提取
  • (二)斐波那契Fabonacci函数
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (汇总)os模块以及shutil模块对文件的操作
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .form文件_一篇文章学会文件上传
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .Net IOC框架入门之一 Unity