分享

在Hibernate应用中Java对象的状态

 hehffyy 2011-01-05
应用程序通过new语句创建一个JAVA对象时,JVM会为这个对象分配一块内存空间,只要这个对象被引用,它就一直存在内存中。如果不被引用了,就结束生命周期,会在适当时候被回收。 

一、理解Session缓存 

Session的save()方法持久化一个对象,这个对象将被加入到Session缓存中,以后即使不再引用这个对象,但是只要Session缓存没有被清空,这个对象仍然会处于生命周期中。 



缓存的作用: 

1.减少访问数据库的频率。 

2.保证缓存中的对象与数据库中的相关记录保持同步。 

3.保证不出现访问对象图的死循环,以及由死循环引起的JVM堆栈溢出异常。清理缓存时,会顺序执行一些SQL语句,具体见书。 



默认情况,Session会在下面的时间清理缓存: 

1.调用commit()方法时 

2.调用find()或者iterate()时,如果缓存中持久化对象的属性变化,则要先清理缓存。 

3.调用flush()方法时。此方法与commit()不同之处:此方法清理后不会提交事务。 

4.例外情况:如果对象用native生成OID,那么当调用save()方法时,会立即执行insert语句。 



如果需要更改Session清理缓存的时间点,用Session的setFlushMode()方法,有三种模式:查询  commit  flush 

FlushMode.AUTO   清理   清理    清理 

FlushMode.COMMIT   不清理   清理   清理 

FlushMode.NEVER   不清理  不清理  清理 

设置代码为:session. setFlushMode(FlushMode.COMMIT); 



在下面的情况,需要调用flush()方法: 

1.使用触发器 

2.混用了Hibernate API和JDBC API 

3.JDBC驱动程序不健壮,导致Hibernate在自动清理缓存模式下无法正常工作。 



二、 在Hibernate应用中Java对象的状态 

需要被持久化的Java对象,在其生命周期中有三种状态: 

1.临时状态:刚用new创建,没被持久化,没在Session缓存中。 

2.持久化状态:被持久化,加入到Session缓存中。 

3.游离状态:被持久化,没在Session缓存中。 



(A) 临时对象 

特征:不在Session缓存中。在数据库中无相应记录。 

如何获得:刚用new创建了一个对象。用Session的delete()方法。 



(B) 持久化对象 

特征:在一个Session实例的缓存中。在数据库中有相应记录。Session清理缓存时,会根据持久化对象的属性变化,来同步更新数据库。 

如何获得: 

用Session的save()方法。 

用Session的load()或get()方法。 

用Session的find()方法。 

用Session的update()、saveOrUpdate()、lock()方法。 

允许级联保存时,如果一个持久化对象关联一个临时对象,Session清理缓存时,会把临时对象转变为持久化对象。 

注意:应避免一个Java对象同时被多个Session实例关联。 



(C) 游离对象 

特征:不在Session缓存中。如果没有其他程序删除其对应的纪录,那么数据库中应该有其纪录。 

获得:用Session的close()方法。用Session的evict()方法,可以从缓存中删除一个持久化对象。 



三、Session的保存、更新、删除、查询方法 

<1>Session的save()方法 

完成操作: 

1.把要保存的对象加入到缓存中,将其变为持久化对象。 

2.选用映射文件指定的标识符生成器为持久化对象分配唯一的OID。(注意,不能修改持久化对象的OID。) 

3.执行一个insert语句。(不是立即执行,而是当Session清理缓存时,才会执行。) 

注意:不能将持久化对象或游离对象传给save()方法。 

<2>Session的update()方法 

完成操作: 

1.把对象重新加入到Session缓存中,使它变为持久化对象。 

2.计划一个update语句,当Session清理缓存时,才会执行。 

如果用update关联了一个游离对象,即使这个对象没有被修改,也会生成update语句。要避免这种情况,可以将映射文件中<class>元素的select-before-update=”true”(默认false),这样Session清理缓存时,会先执行一个select语句,将原来的数据调出来对比是否一致,只有改变了才会执行update。这一方法会导致多select语句,所以如果数据不会经常变化的话,再这样设置。 

注意:不能关联在Session缓存中存在同样OID的游离对象。不能关联在数据库中没有相应记录的游离对象。 

<3>Session的saveOrUpdate()方法 

包含save()和update()方法的功能。遇到临时对象,就调用save;遇到游离对象,调用update();遇到持久化对象,直接返回。 

如何判断是临时or游离对象? 

满足下面情况之一,就是临时对象: 

1.OID取值为null 

2.具有version属性,并取值为null 

3.映射文件的<id>元素设置了unsaved-valued属性,且OID取值与其属性值相符。例如,unsaved-valued=”0”,那么OID为0时是临时对象。 

4. 映射文件的version元素设置了unsaved-valued属性,且version取值与其属性值相符。 

5.自定义了Interceptor实现类,且其isUnsaved()方法返回Boolean.TRUE。 

<4>Session的load()、get()方法 

都根据OID从数据库中加载一个持久化对象。区别:如果不存在于OID对应的纪录,load()抛出异常,get()返回null。 

<5>Session的delete()方法 

删除数据库中与Java对象对应的记录。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多