`
yuzexu
  • 浏览: 3979 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于hibernate联级对象缓存

阅读更多

有部门表(PxDept)和员工表(PxEmployee)关系是PxDept(1)->PxEmployee(N)

首先PxDept.hbm.xml中这样设置

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
	Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
	<class name="hibernate.bean.PxDept" table="px_dept" schema="dbo"
		catalog="test">
		<cache region="read-write"/>
		 <id name="deptId" type="integer">
			<column name="dept_id" />
			<generator class="identity" />
		</id>
		<many-to-one name="pxDept" class="hibernate.bean.PxDept"
			insert="false" update="false">
			<column name="parent_id" />
		</many-to-one>
		<property name="parentDeptId" type="integer">
			<column name="parent_id" />
		</property>
		<property name="deptName" type="string" >
			<column name="dept_name" length="256" not-null="true" />
		</property>
<set name="pxEmployees" inverse="true"  cascade="delete" batch-size="8" lazy="true">
			<cache usage="read-write"/>
			<key>
				<column name="dept_id" not-null="true" />
			</key>
			<one-to-many class="hibernate.bean.PxEmployee" />
		</set>
	</class>
</hibernate-mapping>
我使用以下查询:
(1)List list = session.createQuery("from PxDept as p1 left join fetch p1.pxEmployees").setCacheable(true).list();
(2)list = session.createQuery("from PxDept as p1 left join fetch p1.pxEmployees").setCacheable(true).list();
在(2)中的list结果是从缓存中取的,但里边PxDept对象中的关联对象pxEmployees集合是空的
下面我面又另一种方式:
将PxDept.hbm.xml中的关联关系改下
<set name="pxEmployees" inverse="true"  cascade="delete" batch-size="8" lazy="false">
			<cache usage="read-write"/>
			<key>
				<column name="dept_id" not-null="true" />
			</key>
			<one-to-many class="hibernate.bean.PxEmployee" />
		</set>
lazy="false"
(1)List list = session.createQuery("from PxDept as p1 left join fetch p1.pxEmployees").setCacheable(true).list();
(2)list = session.createQuery("from PxDept as p1 left join fetch p1.pxEmployees").setCacheable(true).list();
这会在(2)中的list 中的pxDept中的pxEmployees集合就有数据了,请问 这什么怎么回事???

 

分享到:
评论
5 楼 yuzexu 2008-07-30  
<p>我找到了解决办法,但还是觉得奇怪</p>
<pre name='code' class='java'>public List createQuery(String sql,Class _class,boolean cache,int page,int pageSize,String queryType,String initializeCollectin) throws HibernateException{
Session session = openSession();
List result = null;
Transaction tx = null;
try{
tx = session.beginTransaction();
Query query = null;
if(DatabaseUtil.QUERY_TYPE_SQL.equalsIgnoreCase(queryType)){
query = session.createSQLQuery(sql);
}else{
query = session.createQuery(sql);
}
if(cache){
query.setCacheable(true).setCacheRegion(_class.getName());
}
if(page&gt;=0 &amp;&amp; pageSize&gt;0){
query.setFirstResult(page * pageSize);
query.setMaxResults((page+1)* pageSize);
}
result = query.list();
if(initializeCollectin!=null &amp;&amp; result!=null &amp;&amp; result.size()&gt;0){
Object entity = result.get(0);
String method = "get" + initializeCollectin.substring(0,1).toUpperCase() + initializeCollectin.substring(1);
try {
Object collection = entity.getClass().getMethod(method).invoke(entity, new Object[]{});
if(!Hibernate.isInitialized(collection)){
Hibernate.initialize(collection);
}
} catch (Exception e) {
e.printStackTrace();
}
}
tx.commit();
}catch(HibernateException he){
if(tx!=null) tx.rollback();
throw he;
}finally{
closeSession();
}
return result;
}
/**
* 根据SQL进行查询
* @param sql
* @param _class
* @param cache
* @param initializeCollection
* @return
* @throws HibernateException
*/
public List createQuery(String sql,String initializeCollection,Class _class,boolean cache) throws HibernateException{
return createQuery(sql,_class,cache,0,0,null,initializeCollection);
}</pre>
<p> 配置文件和以上相同</p>
<p>我执行以下代码:</p>
<pre name='code' class='java'>(1)List list = dbUtil.createQuery("from PxDept","pxEmployees",PxDept.class,true);
(1)中的部门对象中的员工集合是存在的,因为上边的方法中有
                                       if(!Hibernate.isInitialized(collection)){
Hibernate.initialize(collection);
}

(2)list = dbUtil.createQuery("from PxDept","pxEmployees",PxDept.class,true);
但(2)中只有list(0)中的部门对象的员工集合是存在的,其他部门对象的员工集合还是延迟加载的
除非在上边的方法中这样写
if(initializeCollectin!=null &amp;&amp; result!=null &amp;&amp; result.size()&gt;0){

String method = "get" + initializeCollectin.substring(0,1).toUpperCase() + initializeCollectin.substring(1);
try {
Iterator iter  = result.iterator();
                                      while(iter.hasNext()){
                                      Object entity = iter.next();
Object collection = entity.getClass().getMethod(method).invoke(entity, new Object[]{});
if(!Hibernate.isInitialized(collection)){
Hibernate.initialize(collection);
}
if(!cache) break;
                                    }
} catch (Exception e) {
e.printStackTrace();
}
}
</pre>
<p> 也就是说,在不使用缓存的情况下,只要在session关闭之前任意加载一下部门中的员工集合,其他部门下的员工集合也会被加载</p>
<p>但是在用缓存的情况下,在session关闭之前必须遍历所有部门将其下的员工集合都用hibernate.initialize(pxEmployees)一下才可,</p>
<p> </p>
<p>有点疑惑??</p>
4 楼 movingboy 2008-07-29  
我想了几种可能性,但都不敢肯定。我搜索了Hibernate的官方论坛,想找到与你的问题类似的帖子,但没有找到。不过看到其它关于cache和collection有关的帖子,发觉问题不少。比如有人提交了一个缺陷:http://opensource.atlassian.com/projects/hibernate/browse/HHH-2350

建议你也到Hibernate的官方论坛(http://forum.hibernate.org/viewforum.php?f=1)里查一查有没有与你的问题类似的帖子,或者把你的问题贴上去,看看有没有人能帮你解答一下
3 楼 yuzexu 2008-07-29  
请问下,你们没有遇到过hibernate关于联级对象缓存的问题吗
2 楼 movingboy 2008-07-29  
猜测,仅仅是猜测:如果你用Spring作为容器,试试OpenSessionInView,看看能否在lazy=true的情况下仍能得到pxDept中的pxEmployees集合的数据?
1 楼 yuzexu 2008-07-29  
怎么没人回答?

相关推荐

    hibernate与mybatis一起使用取长补短

    6. **缓存策略**: Hibernate的二级缓存可以用于提高数据访问速度,而MyBatis可以通过插件实现自己的缓存机制,两者结合可以构建更高效的缓存体系。 7. **错误调试**: MyBatis的SQL日志记录功能可以帮助开发者快速...

    Hibernate

    - **内置缓存**:Hibernate默认提供的一级缓存。 - **外置缓存**:可通过配置使用第三方缓存插件(如EHCache)来扩展缓存功能。 #### Hibernate事务管理 - **事务特性**: - **原子性**(Atomicity):事务中的...

    Java Persistence with Hibernate(Revised Edition of Hibernate in Action)

    5. **缓存机制**:介绍了第一级缓存和第二级缓存,以及如何利用缓存提高应用程序性能。 6. **复杂映射**:包括一对多、多对一、一对一、多对多等关联关系的映射,以及自联映射和集合映射。 7. **性能优化**:提供...

    hibernate帮助文档

    1. 联级加载与懒加载:初始化关联对象的策略,前者在加载父对象时同时加载子对象,后者在需要时才加载。 2. 自动更新与脏检查:Hibernate自动检测对象状态变化并同步到数据库。 3. 异常体系:Hibernate有自己的异常...

    ssh面试题 txt文档

    根据提供的文件信息,我们可以整理出以下关于SSH(Struts + Spring + Hibernate)框架的重要知识点: ### 1. Hibernate 的基本操作流程 - **获取配置文件**:首先需要加载配置文件,通常为`hibernate.cfg.xml`。 -...

    基于ssh框架的省市区级联

    接下来,Hibernate作为ORM(对象关系映射)工具,简化了数据库操作。在省市区级联的案例中,我们需要设计省、市、区三个实体类,每个实体类对应数据库中的一个表。通过Hibernate的注解或XML配置,可以定义实体类与表...

    IBATIS.pdf

    Hibernate采用了传统的对象关系映射(ORM)技术,能够自动将Java对象映射到数据库表,并自动生成相应的SQL语句,这在处理常见的CRUD(Create, Read, Update, Delete)操作和查找标准条件时非常高效。Hibernate的另一...

    jsp及java的学习指导

    4. **数据库SQL基础**:熟悉SQL语言,包括基本的增删改查操作,以及更复杂的联表查询和子查询。这对于任何涉及到数据库的应用程序都是必需的。 5. **JDBC编程**:理解JDBC的工作原理,学习如何连接数据库,执行SQL...

    java学习路线.docx

    12. **企业级技术**:掌握Maven构建工具,Redis缓存技术,以及日志管理库log4j,这些都是大型项目中的常见组件。 13. **Linux基础**:了解Linux命令行操作,因为大多数服务器运行在Linux环境下。 学习要求方面,你...

    深圳技术搜集(2).docx

    - **ORM框架**: 如Hibernate、MyBatis等,用于实现对象关系映射。 - **工作流框架**: 如Activiti等,用于管理业务流程。 - **IoC框架**: 如Spring等,用于实现依赖注入。 - **路由框架**: 如Camel等,用于构建...

    新巴巴运动网

    - **多级联查询:** 实现了省市区三级联动的数据查询功能。 - **异步图片上传:** 使用异步技术上传图片至后端服务器,提高用户体验。 - **图片服务器分离:** 将图片存储于独立的图片服务器上,优化资源加载速度...

    java学习路线

    - **缓存技术**:了解Hibernate的缓存机制。 - **性能优化**:学会如何优化Hibernate的性能。 **3. Spring(重点)** - **IOC、AOP**:理解依赖注入和面向切面编程的概念。 - **DataSource**:掌握Spring中的数据源...

    java面试题

    - **缓存管理**:一级缓存(session缓存)和二级缓存(全局缓存),提高数据访问性能。 #### 多线程应用与机制 - **线程创建**:通过继承Thread类或实现Runnable接口。 - **线程同步**:synchronized关键字、...

    java高级工程师面试总结

    - Hibernate是一个全功能的ORM框架,支持懒加载、缓存、事务管理等特性。 - MyBatis是一个半自动的ORM框架,更适合复杂的SQL查询和定制化需求。 - **Hibernate延迟加载的机制**: - 延迟加载是指在需要的时候才...

    基于Springboot+Vue的库存管理系统源码案例设计带文档说明.zip

    2. **Hibernate**:作为JPA的实现之一,提供了强大的对象关系映射功能。 3. **SQL查询**:可能包含复杂的联表查询、分页查询等,用于获取库存数据。 【文档说明】 项目通常会附带详细的使用文档,指导如何运行项目...

Global site tag (gtag.js) - Google Analytics