- 浏览: 2294173 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (314)
- JAVA基础知识 (54)
- Java-IO/FIle (16)
- Java-JDBC (4)
- JAVA-新增特性-注解 (3)
- Java-枚举 (2)
- Java-泛型 (1)
- Java-多线程 (15)
- Java-XML (4)
- Java-JMS(消息服务) (4)
- Java-JVM (0)
- Web Service服务 (7)
- Jsp (10)
- js (18)
- Struts框架 (11)
- Spring框架 (29)
- Hibernate框架 (28)
- Spring Boot框架 (2)
- ExtJS前端框架 (29)
- Jquery js库 (8)
- JUnit框架 (8)
- Selenium 测试 (1)
- NoSql---Redis (6)
- ORACLE数据库 (45)
- MySQL数据库 (4)
- tomcat (3)
- Nginx反向代理服务器 (4)
- web应用服务器通用知识 (3)
- 开发工具IDE (14)
- UML建模 (1)
- SVN CVS 版本管理 (6)
- git 分布式版本管理 (4)
- 报表设计 (5)
- 文件上传下载 (2)
- 数据算法 (1)
- 存储过程 (5)
- JSON 相关 (1)
- OGNL表达式 (3)
- Util工具包 (9)
- 设计模式 (15)
- linux 相关 (3)
- life think (3)
- 工作流管理框架 (1)
- 大数据-Hadoop (1)
最新评论
-
huih:
很不错的文章
SpringMVC+Hibernate+Spring 简单的一个整合实例 -
calm01:
学习了.
Spring <bean>标签属性 Autowire自动装配(转载) -
lizhenlzlz:
我的也是拦截不了service层
SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)(转载) -
josh_123:
讲的不错,很详细,如果quartz定时任务类采用不继承任何类的 ...
Spring,jdk定时任务的几种实现以及任务线程是串行还是并行执行(转载) -
human_coder:
你知道eclipse调试怎么可以回调吗?有时候总是调快了,不能 ...
Debug---Eclipse断点调试基础
当你显式的使用session.save()或者session.update()操作一个对象的时候,实际上是用不到unsaved-value的。某些情况下(父子表关联保存),当你在程序中并没有显式的使用save或者update一个持久对象,那么Hibernate需要判断被操作的对象究竟是一个已经持久化过的持久对象,是一个尚未被持久化过的内存临时对象。例如:
- 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 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)这样的操作。
因此我们需要暗示一下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。
unsaved-value="null" (默认情况,适用于大多数对象类型主键 Integer/Long/String/...)
当Hibernate取一下child的Id,取出来的是null(在上例中肯定取出来的是null),和unsaved-value设定值相等,发送save(child)
当Hibernate取一下child的id,取出来的不是null,那么和unsaved-value设定值不相等,发送update(child)
例如下面的情况:
- 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();;
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类的主键属性中的。
- <class name="Child" table="child">
- <id column="id" name="id" type="integer" unsaved-value="null">
- <generator class="identity"/>
- </id>
- ...
- </class>
<class name="Child" table="child">
<id column="id" name="id" type="integer" unsaved-value="null">
<generator class="identity"/>
</id>
...
</class>
如果主键属性不是对象型,而是基本类型,如int/long/double/...,那么你需要指定一个数值型的unsaved-value,例如:
unsaved-null="0"
在此提醒大家,很多人以为对主键属性定义为int/long,比定义为Integer/Long运行效率来得高,认为基本类型不需要进行对象的封装和解构操作,因此喜欢把主键定义为int/long的。但实际上,Hibernate内部总是把主键转换为对象型进行操作的,就算你定义为int/long型的,Hibernate内部也要进行一次对象构造操作,返回给你的时候,还要进行解构操作,效率可能反而低也说不定。因此大家一定要扭转一个观点,在Hibernate中,主键属性定义为基本类型,并不能够比定义为对象型效率来的高,而且也多了很多麻烦,因此建议大家使用对象型的Integer/Long定义主键。
unsaved-value="none"和
unsaved-value="any"
主主要用在主键属性不是通过Hibernate生成,而是程序自己setId()的时候。
在这里多说一句,强烈建议使用Hibernate的id generator,或者你可以自己扩展Hibernate的id generator,特别注意不要使用有实际含义的字段当做主键来用!例如用户类User,很多人喜欢用用户登陆名称做为主键,这是一个很不好的习惯,当用户类和其他实体类有关联关系的时候,万一你需要修改用户登陆名称,一改就需要改好几张表中的数据。偶合性太高,而如果你使用无业务意义的id generator,那么修改用户名称,就只修改user表就行了。
由这个问题引申出来,如果你严格按照这个原则来设计数据库,那么你基本上是用不到手工来setId()的,你用Hibernate的id generator就OK了。因此你也不需要了解当
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了,根据你自己的需要来定。
BTW: Gavin King强烈不建议使用composite-id,强烈建议使用UserType。
因此,如果你在系统设计的时候,遵循如下原则:
1、使用Hibernate的id generator来生成无业务意义的主键,不使用有业务含义的字段做主键,不使用assigned。
2、使用对象类型(String/Integer/Long/...)来做主键,而不使用基础类型(int/long/...)做主键
3、不使用composite-id来处理复合主键的情况,而使用UserType来处理该种情况。
那么你永远用的是unsaved-value="null" ,不可能用到any/none/..了。
发表评论
-
教你使用Hibernate的QBC查询(转载)
2015-12-18 17:19 4190转载自:http://developer.51cto.com ... -
hibernatesynchronizer3开发工具的使用方法
2014-11-24 14:35 25581. hibernatesynchronizer3可以帮助 ... -
Hibernate锁机制(悲观锁,乐观锁)
2014-09-24 17:16 2045锁(locking) 业务逻辑的实现过程中,往往需要保证 ... -
六种方式实现hibernate查询,及IDE推荐 (转载)
2014-07-16 18:13 1222hibernate查询的6种方法。分别是HQL查询,对象 ... -
SpringMVC+Hibernate+Spring 简单的一个整合实例
2014-07-04 16:14 87673SpringMVC又一个漂亮的web框架,他与Struts2 ... -
Struts2、hibernate和spring下载,整合所需jar包
2014-07-04 16:00 4426ssh三个框架各自所有版本下载地址如下 Struts f ... -
Hibernate Criteria的 Criterion,Projection,Restrictions等条件设置
2014-04-01 16:46 37980在查询方法设计上可以灵活的根据Criteria的特点来方便 ... -
Hibernate的Example示例查询
2013-07-29 17:32 3976org.hibernate.criterion.Ex ... -
Spring与Hibernate集成中的session问题
2013-04-15 15:53 31341.通过getSession()方法 ... -
剖析Hibernate主键生成几种常用方式
2012-12-05 20:01 12881.assigned: 主键由外部程序负责生成,无需H ... -
正确理解Hibernate Inverse (转)
2012-12-05 11:02 1332通过Hibernate Inverse的设 ... -
Hibernate中session.getconnection()的替代方法
2012-08-27 16:39 51402010-04-15 10:21 Hibernate ... -
Hql总结 查询结果动态组装成List(map),List(bean),List(list),List(set)等格式(转)
2012-08-17 15:51 72891.//查询整个对象String hql="from ... -
sql和hql中join语句区别,以及hibernate中内连接,迫切内连接,左外连接,迫切左外连接,右外连接的区别(合集)
2012-07-24 17:39 3141第一:sql和hql中join语 ... -
Hibernate_HQL--实体、属性查询,参数绑定,引用查询(随时温习一遍)
2012-07-05 17:52 15885是Hibernate官方推荐的查询模式,比Criteria功能 ... -
hibernate里createSQLQuery的addEntity()和setResultTransformer()方法
2012-06-21 10:55 564761. 使用SQLQuery对原生SQL查询执行的控制是通过S ... -
hibernate的session.connection被session.dowork()替代
2012-06-14 10:22 4050Hibernate3.3.2版本中getSessi ... -
Hibernate继承映射多态的详解
2012-06-05 17:36 1927在面向对象的程序领域中,类与类之间是有继承关系的,例如Java ... -
hibernateTemplate session关闭
2012-04-18 14:53 37371.虽然继承了HibernateDaoSupport这个类,但 ... -
No Hibernate Session bound to thread, and configuration does not allow creation
2012-04-18 10:57 2145用SessionFactory.getCurrentSessi ...
相关推荐
21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 23.1. Employer(雇主)/...
21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 23.1. Employer(雇主)/...
21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 23.1. Employer(雇主)/...
21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 23.1. Employer(雇主)/Employee...
21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 23.1. Employer(雇主)/...
21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 23.1. Employer(雇主)/...
21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 23.1. Employer(雇主)/Employee...
21.4. Cascades and unsaved-value 21.5. Conclusion 22. Example: Weblog Application 22.1. Persistent Classes 22.2. Hibernate Mappings 22.3. Hibernate Code 23. Example: Various Mappings 23.1. Employer/...
22.4. 级联与未保存值(Cascades and unsaved-value) 22.5. 结论 23. 示例:Weblog 应用程序 23.1. 持久化类 23.2. Hibernate 映射 23.3. Hibernate 代码 24. 示例:复杂映射实例 24.1. Employer(雇主)/...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 23.1. Employer(雇主)/Employee...
22.4. 级联与未保存值(Cascades and unsaved-value) 22.5. 结论 23. 示例:Weblog 应用程序 23.1. 持久化类 23.2. Hibernate 映射 23.3. Hibernate 代码 24. 示例:复杂映射实例 24.1. Employer(雇主)/...
2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二...
21.4. 级联与未保存值(Cascades and unsaved-value) 21.5. 结论 22. 示例:Weblog 应用程序 22.1. 持久化类 22.2. Hibernate 映射 22.3. Hibernate 代码 23. 示例:复杂映射实例 ……………………
关于 unsaved-value ............................................................................... 59 Inverse 和 Cascade ......................................................................... 61 ...
1.1. Part 1 - The first Hibernate Application ................................................................ 1 1.1.1. Setup .............................................................................