- 浏览: 82739 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
wzwahl36:
文章很赞!http://www.atool.org/img2b ...
Base64编码的图片在网页中的显示问题的解决 -
mllongze:
haidage 写道小伙,你头像真磕碜。那是我最帅的一张
JAVA实现约瑟夫环 -
haidage:
小伙,你头像真磕碜。
JAVA实现约瑟夫环 -
mllongze:
angelgreen 写道恩 谢谢啊 rpm安装 不用 呵呵 ...
linux下rpm安装时遇到的问题 -
mllongze:
haidage 写道你要干嘛 咋地 没看到嘛 常用的计算符号 ...
常用特殊符号
今天做程序时发现Hibernate.initialize()方法! 查了一下资料找到一篇文章感觉不错很容易理解在此分享!
学习中……
==============================================
在使用hibernate进行持久化时,有时需要动态的改变对象的加载,比如在编辑页面里面lazy=true,而在浏览页面lazy=false,这样可以在需要lazy的地方才进行控制。而配置文件中Lazy属性是全局控制的,如何处理呢?
在配置文件里面可以用lazy=true,在程序里面可以用强制加载的方法Hibernate.initialize(Object proxy) 方法强制加载这样就相当于动态改变为lazy=false。
但在使用时需要注意的一点是:其中的proxy是持久对象的关联对象属性,比如A实体,你要把A的关联实体B也检出,则要写Hibernate.initialize(a.b)。
==============================================
hibernate(po,vo,unsave-value,inverse,cascade,lazy-loading)
PO 即Persistence Object
VO 即Value Object
PO 和VO 是Hibernate 中两个比较关键的概念。
首先,何谓VO,很简单,VO 就是一个简单的值对象。
如:
TUser user = new TUser();
user.setName("Emma");
这里的user 就是一个VO。VO 只是简单携带了对象的一些属性信息。
何谓PO? 即纳入Hibernate 管理框架中的VO。看下面两个例子:
TUser user = new TUser();
TUser anotherUser = new TUser();
user.setName("Emma");
anotherUser.setName("Kevin");
//此时user和anotherUser都是VO
Transaction tx = session.beginTransaction();
session.save(user);
//此时的user已经经过Hibernate的处理,成为一个PO ,而anotherUser仍然是个VO
tx.commit();
//事务提交之后,库表中已经插入一条用户”Emma”的记录,对于anotherUser则无任何操作
Transaction tx = session.beginTransaction();
user.setName("Emma_1"); //PO
anotherUser.setName("Kevin_1");//VO
tx.commit();
//事务提交之后,PO的状态被固化到数据库中,也就是说数据库中“Emma”的用户记录已经被更新为“Emma_1”,此时anotherUser仍然是个普通Java对象,它的属性更改不会对数据库产生任何影响,另外,通过Hibernate返回的对象也是PO: 由Hibernate返回的PO ,如:
TUser user = (TUser)session.load(TUser.class,new Integer(1));
VO经过Hibernate进行处理,就变成了PO。上面的示例代码session.save(user)中,我们把一个VO “user”传递给Hibernate的Session.save方法进行保存。在save方法中,Hibernate对其进
行如下处理:
1. 在当前session所对应的实体容器(Entity Map)中查询是否存在user对象的引用。
2. 如果引用存在,则直接返回user对象id,save过程结束. Hibernate中,针对每个Session有一个实体容器(实际上是一个Map对象),如果此容器中已经保存了目标对象的引用,那么hibernate 会认为此对象已经与Session相关联。
对于save操作而言,如果对象已经与Session相关联(即已经被加入Session 的实体容器中),则无需进行具体的操作。因为之后的Session.flush 过程中,Hibernate会对此实体容器中的对象进行遍历,查找出发生变化的实体,生成并执行相应的update语句。
3. 如果引用不存在,则根据映射关系,执行insert操作。
a) 在我们这里的示例中,采用了native的id生成机制,因此hibernate会从数据库取得insert操作生成的id并赋予user对象的id属性。
b) 将user对象的引用纳入Hibernate的实体容器。
c) save 过程结束,返回对象id.
而Session.load方法中,再返回对象之前,Hibernate 就已经将此对象纳入其实体容器中。
VO和PO的主要区别在于:
. VO是独立的Java Object。
. PO是由Hibernate纳入其实体容器(EntityMap)的对象,它代表了与数
据库中某条记录对应的Hibernate实体,PO的变化在事务提交时将反应到实
际数据库中。如果一个PO与Session对应的实体容器中分离(如Session 关闭后的PO),那么
此时,它又会变成一个VO。
关于unsaved-value
在非显示数据保存时,Hibernate 将根据这个值来判断对象是否需要保存。
所谓显式保存,是指代码中明确调用session 的save 、update 、saveOrupdate 方法对对象进行持久化。如:
session.save(user);
而在某些情况下,如映射关系中,Hibernate 根据级联(Cascade )关系对联接类进行保存。此时代码中没有针对级联对象的显示保存语句,需要Hibernate 根据对象当前状
态判断是否需要保存到数据库。此时,Hibernate 即将根据unsaved-value 进行判定。
首先Hibernate 会取出目标对象的id。之后,将此值与unsaved-value 进行比对,如果相等,则认为目标对象尚未保存,否则,认为对象已经保存,无需再进行保存操作。
如:user 对象是之前由hibernate 从数据库中获取,同时,此user 对象的若干个关联对象address 也被加载,此时我们向user 对象新增一个address 对象,此时调用
session.save(user),hibernate 会根据unsaved-value 判断user 对象的数个address
关联对象中,哪些需要执行save 操作,而哪些不需要。
对于我们新加入的address 对象而言,由于其id(Integer 型)尚未赋值,因此为null,与我们设定的unsaved-value(null )相同,因此hibernate 将其视为一个未保存对象,将为其生成insert 语句并执行。
这里可能会产生一个疑问,如果“原有”关联对象发生变动(如user 的某个“原有” 的address 对象的属性发生了变化,所谓“原有”即此address 对象已经与user 相关联,而不是我们在此过程中为之新增的),此时id 值是从数据库中读出,并没有发生改变,自然
与unsaved-value(null)也不一样,那么Hibernate 是不是就不保存了?
上面关于PO、VO 的讨论中曾经涉及到数据保存的问题,实际上,这里的“保存”,实际上是“insert”的概念,只是针对新关联对象的加入,而非数据库中原有关联对象的
“update”。所谓新关联对象,一般情况下可以理解为未与Session 发生关联的VO。而“原有”关联对象,则是PO。:
对于save操作而言,如果对象已经与Session相关联(即已经被加入Session的实体容器中),则无需进行具体的操作。因为之后的Session.flush 过程中,Hibernate
会对此实体容器中的对象进行遍历,查找出发生变化的实体,生成并执行相应的update 语句。
Inverse和Cascade
Inverse,直译为“反转”。在Hibernate语义中,Inverse 指定了关联关系中的方向。关联关系中,inverse=”false”的为主动方,由主动方负责维护关联关系。具体可参见一对多关系中的描述。
而Cascade,译为“级联”,表明对象的级联关系,如TUser 的Cascade设为all,就表明如果发生对user对象的操作,需要对user所关联的对象也进行同样的操作。如对user对象执行save操作,则必须对user对象相关联的address也执行save操作。
初学者常常混淆inverse和cascade,实际上,这是两个互不相关的概念。Inverse 指的是关联关系的控制方向,而cascade指的是层级之间的连锁操作。
延迟加载(Lazy Loading)
为了避免一些情况下,关联关系所带来的无谓的性能开销。Hibernate引入了延迟加载的概念。如,示例中user对象在加载的时候,会同时读取其所关联的多个地址(address)对象,
对于需要对address进行操作的应用逻辑而言,关联数据的自动加载机制的确非常有效。但是,如果我们只是想要获得user的性别(sex)属性,而不关心user的地址(address)
信息,那么自动加载address的特性就显得多余,并且造成了极大的性能浪费。为了获得user 的性别属性,我们可能还要同时从数据库中读取数条无用的地址数据,这导致了大量无谓的系统开销。
延迟加载特性的出现,正是为了解决这个问题。所谓延迟加载,就是在需要数据的时候,才真正执行数据加载操作。
对于我们这里的user对象的加载过程,也就意味着,加载user对象时只针对其本身的属性,而当我们需要获取user对象所关联的address信息时(如执行user.getAddresses时),才
真正从数据库中加载address数据并返回。
尝试执行以下代码:
Criteria criteria = session.createCriteria(TUser.class);
criteria.add(Expression.eq("name","Erica"));
List userList = criteria.list();
TUser user =(TUser)userList.get(0);
System.out.println("User name => "+user.getName());
Set hset = user.getAddresses();
session.close();//关闭Session
TAddress addr = (TAddress)hset.toArray()[0];
System.out.println(addr.getAddress());
运行时抛出异常:
LazyInitializationException - Failed to lazily initialize a collection - no session or session was closed
如果我们稍做调整,将session.close放在代码末尾,则不会发生这样的问题。这意味着,只有我们实际加载user 关联的address时,Hibernate 才试图通过
session从数据库中加载实际的数据集,而由于我们读取address之前已经关闭了session,所以报出session已关闭的错误。
这里有个问题,如果我们采用了延迟加载机制,但希望在一些情况下,实现非延迟加载时的功能,也就是说,我们希望在Session关闭后,依然允许操作user的addresses
属性。如,为了向View层提供数据,我们必须提供一个完整的User对象,包含其所关联的address信息,而这个User对象必须在Session关闭之后仍然可以使用。
Hibernate.initialize方法可以通过强制加载关联对象实现这一功能:
Hibernate.initialize(user.getAddresses());
session.close();
//通过Hibernate.initialize方法强制读取数据
//addresses对象即可脱离session进行操作
Set hset= user.getAddresses();
TAddress addr = (TAddress)hset.toArray()[0];
System.out.println(addr.getAddress());
为了实现透明化的延迟加载机制,hibernate进行了大量努力。其中包括JDK Collection接口的独立实现。
如果我们尝试用HashSet强行转化Hibernate返回的Set 型对象:
Set hset = (HashSet)user.getAddresses();
就会在运行期得到一个java.lang.ClassCastException, 实际上,此时返回的是一个Hibernate的特定Set实现“net.sf.hibernate.collection.Set”对象,而非
传统意义上的JDK Set实现。这也正是我们为什么在编写POJO时,必须用JDKCollection 接口(如Set,Map), 而非特定的JDKCollection 实现类(如HashSet、HashMap)申明Collection属性的原因
发表评论
-
Cross Frame 与不同域进行交互
2011-11-04 11:25 2155为何要用不同网域的 Iframe? 通常较具规模的网站, ... -
数据库连接池技术中dbcp、c3p0、jndi
2011-10-21 16:54 1212不管通过何种持久化技术,都必须通过数据连接访问数据库,在Spr ... -
JAVA实现约瑟夫环
2011-10-12 11:59 927//实现约瑟夫环 public class Josephus ... -
java.lang.NoClassDefFoundError: net/sf/ezmorph/Morpher
2011-09-22 12:58 994使用JSON,在SERVLET或者STRUTS的ACTION中 ... -
六条比较有用的MySQL的SQL语句
2011-09-22 12:08 775本文给大家介绍六条比较有用的MySQL的SQL语句,可能很多人 ... -
linux下rpm安装时遇到的问题
2011-09-22 12:07 1182在Linux下安装rpm包时经常会遇到下面这个问题: ... -
JS 常用经典小技巧==(不断更新)
2011-09-22 12:06 939一、1. X.replace(/\"/g," ... -
ajax提交特殊字符编码转换问题.ishexdigit问题-解决方案
2011-09-22 12:03 2029今天测试密码输入了一串特殊字符后后台出来如下错误: 2010 ... -
JS逻辑运算符&&与||的妙用
2011-09-22 12:01 4695/* 文章写的不错 就此分享 */ &&中第一 ... -
JavaScript学习笔记(一)---Curry化技术/几个页面加载的区别
2011-04-28 17:36 2595Curry化技术是一种通过 ... -
不能使用Hibernate Reverse Engineering生成实体类的原因(转)
2011-04-28 16:00 1170/*取自http://tonysmith.iteye.com/ ... -
web.xml解析
2011-04-28 15:35 1480【1】.web.xml头文件 <?xml version ... -
Myeclipse6.5反编译工具----jadclipse
2011-04-25 16:17 1212一。将解压后的jad.exe文件复制到java\jdk\bin ... -
Hibernate Criteria 学习
2011-04-21 11:04 639/*此文章网上摘录 仅供自己学习使用*/ 设计上可以灵活的 ... -
Base64编码的图片在网页中的显示问题的解决
2011-03-21 17:17 84121.为什么要用到BASE64编码的图片信息 Base6 ... -
JQuery的Cookies插件
2011-03-18 16:46 1799在使用jquery.cookies.2.2.0.js的插件时是 ... -
Hibernate 映射文件在不联网的时候 处理DTD方法
2011-03-18 16:16 1291这个问题应该是在做hibernate项目中遇到的比较常见的问题 ... -
DOM 创建 Select 加入Option
2011-03-17 11:19 851(转载....) 注意:Option中的O是要大写的,不然语法 ... -
Hibernate继承分页BUG解决方法之一
2011-03-09 16:08 1032(转载) 今天遇到了一个大问题,hibernate的继承分页b ... -
javascript cookies 存、取、删除实例
2011-03-09 14:51 863(转载 javascript cookies技术 。。。。 ...
相关推荐
在描述"延迟加载类Lazy的使用示例"中,我们可以预期在`Lazy.Object.Initialize.Console`这个项目中包含一个使用`Lazy<T>`的控制台应用程序示例。这个示例可能展示了如何在多线程环境中利用`Lazy<T>`确保安全初始化,...
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:225) at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService...
标题 "解析 this.initialize.apply(this, arguments)" 涉及到的是JavaScript编程中的一个关键概念,尤其是在对象构造和类继承的情景下。`this` 关键字在JavaScript中扮演着核心角色,它指的是函数调用时的上下文,而...
当你尝试在Controller层或者视图层访问懒加载的属性时,如果Session已经关闭("no Session..."错误),就会抛出`org.hibernate.LazyInitializationException`。这是因为懒加载的代理对象需要Session来执行数据库查询...
Ajax-jquery.initialize.zip,用于动态创建元素初始化的jquery插件(几年前很好,在2019年 考虑react或其他东西而不是jquery),ajax代表异步javascript和xml。它是多种web技术的集合,包括html、css、json、xml和...
避免这个问题的方法是在访问懒加载属性之前确保Session仍然打开,或者显式地在需要时加载属性,如使用`Hibernate.initialize()`方法。 ### 5. MappingException - **MappingException: Error reading resource**:...
jquery.initialize 1.4.0 1.4.0 之前的最新更新:添加了子元素数据绑定。 最新更新至 1.3.0:数据属性、模板属性和字符串模板替换。 一个简单的 jQuery 元素初始值设定项上下文插件。 该插件使元素初始化并将定义...
错误表现:在Session关闭后尝试访问懒加载属性,抛出“org.hibernate.LazyInitializationException: could not initialize proxy - no Session”异常。 解决方案:理解并合理使用Open Session in View(OSIV)模式...
\\.\Global\vmx86虚拟机启动过程中,报这种错误,然后启动不了。 本文档可以很好的解决这个问题。
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter <filter-name>OpenSessionInViewFilter *.action ``` 在上面的配置中,我们定义了一个名为 OpenSessionInViewFilter 的 ...
- 解决方法之一是在关闭 Session 之前加载关联对象,如通过 `session.evict(user)` 或 `Hibernate.initialize(user.getPermissions())`。 - 另一种解决办法是在 HQL 查询或 Criteria 查询中使用 Join Fetching。 ...
- 如果采用了延迟加载机制但希望在某些情况下实现非延迟加载,可以通过`Hibernate.initialize()`方法强制加载关联对象。 #### 十一、对象持久化操作 - 对于`save`操作,如果对象已经与`Session`关联,则无需额外...
import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.cfg.Configuration; /** * Configures and provides access to Hibernate sessions, tied to the * current ...
Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed ``` - **日志记录**:为了更好地诊断问题,可以使用log4j等工具进行日志...
如果需要立即加载对象,可以使用`Hibernate.initialize()`方法。 在映射文件中,我们需要为Java类型指定对应的Hibernate类型,例如: - 基本类型及其封装类:整数、浮点数、字符型、布尔型等。 - 字符串:使用`...
- 使用`Class.forName(String className)`或`Class.forName(String className, boolean initialize, ClassLoader loader)`方法显式加载类。 - 使用`ClassLoader.loadClass(String name)`方法显式加载类。 其中,`...
在 Web 应用中,为了初始化对象关系,可能需要使用 Hibernate 的 `initialize()` 方法,如 `Hibernate.initialize(student.getFriends())` 来加载关联的对象。此外,`<property name="show_sql">true</property>` ...
`org.hibernate.persister.collection.AbstractCollectionPersister`和`org.hibernate.action.internal.CollectionRemoveAction`等类是处理多对多关联删除的关键。通过阅读源码,我们可以了解到Hibernate如何处理...
标题 "Could not initialize class net.sf.jasperreports.engine.util.JRStyledTextParser" 提示了一个Java运行时错误,这通常意味着在尝试加载或初始化`JRStyledTextParser`类时遇到了问题。`JRStyledTextParser`是...
Hibernate Validator 是一个强大的Java Bean验证框架,它是Hibernate项目的一部分,实现了JSR-303(Bean Validation 1.0)和JSR-349(Bean Validation 1.1)标准,提供了对对象模型的验证功能。在版本5.1.2.Final中...