浏览 2645 次
锁定老帖子 主题:关于hibernate联级对象缓存
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-07-28
有部门表(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集合就有数据了,请问 这什么怎么回事???
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-07-29
怎么没人回答?
|
|
返回顶楼 | |
发表时间:2008-07-29
猜测,仅仅是猜测:如果你用Spring作为容器,试试OpenSessionInView,看看能否在lazy=true的情况下仍能得到pxDept中的pxEmployees集合的数据?
|
|
返回顶楼 | |
发表时间:2008-07-29
请问下,你们没有遇到过hibernate关于联级对象缓存的问题吗
|
|
返回顶楼 | |
发表时间:2008-07-29
我想了几种可能性,但都不敢肯定。我搜索了Hibernate的官方论坛,想找到与你的问题类似的帖子,但没有找到。不过看到其它关于cache和collection有关的帖子,发觉问题不少。比如有人提交了一个缺陷:http://opensource.atlassian.com/projects/hibernate/browse/HHH-2350
建议你也到Hibernate的官方论坛(http://forum.hibernate.org/viewforum.php?f=1)里查一查有没有与你的问题类似的帖子,或者把你的问题贴上去,看看有没有人能帮你解答一下 |
|
返回顶楼 | |
发表时间:2008-07-30
我找到了解决办法,但还是觉得奇怪 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>=0 && pageSize>0){ query.setFirstResult(page * pageSize); query.setMaxResults((page+1)* pageSize); } result = query.list(); if(initializeCollectin!=null && result!=null && result.size()>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); } 配置文件和以上相同 我执行以下代码: (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 && result!=null && result.size()>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(); } } 也就是说,在不使用缓存的情况下,只要在session关闭之前任意加载一下部门中的员工集合,其他部门下的员工集合也会被加载 但是在用缓存的情况下,在session关闭之前必须遍历所有部门将其下的员工集合都用hibernate.initialize(pxEmployees)一下才可,
有点疑惑?? |
|
返回顶楼 | |