Rory's Blog
Happy study,Happy work,Happy life
posts - 22,  comments - 46,  trackbacks - 0
上篇文章:《今天发现一个hibernate的bug,或者说一个应该注意的地方比较合适 》里面我提到了Hibernate查询需要注意的一个问题。今天发现了一个最好的解决办法。如果大家现在用Hibernate,相信大家都回用到DetachedCriteria.关于DetachedCriteria查询请查看http://dev.yesky.com/241/2033241.shtml
      DetachedCriteria给我们的Hibernate查询带来了很多方便,但是如果你带上排序信息就会出现我的上一篇文章里面说的那种错误,今天发现一个很好的解决方法,其实也很简单。就是先把传入的带Order信息的DetachedCriteria去掉order信息查询数据总条数,然后再把Order加回来查询满足条件的对象。通过查看Hibernate的源代码发现Criteria的实现CriteriaImpl发现其实addOrder是给private List orderEntries = new ArrayList();这个List加值。这个List里面放的是OrderEntry对象。这个OrderEntry里面放了一个criteria 和 order.

    
    public PaginationSupport findPageByCriteria(final DetachedCriteria detachedCriteria, final int pageSize, final int startIndex) {
        
return (PaginationSupport) getHibernateTemplate().execute(new HibernateCallback() {
            
public Object doInHibernate(Session session) throws HibernateException {
                Criteria criteria 
= detachedCriteria.getExecutableCriteria(session);
                CriteriaImpl impl 
= (CriteriaImpl) criteria;
                List orderEntrys 
= new ArrayList();
                
try{
                    Field field 
= CriteriaImpl.class.getDeclaredField("orderEntries");
                    
//Get orders
                    orderEntrys = (List) field.get(impl);
                    
//Remove orders
                    field.set(criteria,new ArrayList());
                }
catch(Exception ex){
                    ex.printStackTrace();
                    
//TODO xxxx
                }
                
int totalCount = ((Integer) criteria.setProjection(Projections.rowCount())
                        .uniqueResult()).intValue();
                criteria.setProjection(
null);
                
                
try{
                    Field field 
= CriteriaImpl.class.getDeclaredField("orderEntries");
                    
//Add orders return
                    for(int i=0; i<orderEntrys.size(); i++){
                        List innerOrderEntries 
= (List) field.get(criteria);
                        innerOrderEntries.add(orderEntrys.get(i));
                    }
                }
catch(Exception ex){
                    ex.printStackTrace();
                    
//TODO cccc
                }
                List items 
= criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();
                PaginationSupport ps 
= new PaginationSupport(items, totalCount, pageSize,
                        startIndex);
                
return ps;
            }
        }, 
true);
    }
希望大家多多交流
posted on 2006-05-29 23:29 莫多 阅读(4971) 评论(12)  编辑  收藏 所属分类: WebworkSpring

FeedBack:
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
2006-06-06 21:10 | Tin
才发现我们遇到了类似的问题,前几天看你这篇Blog还没看明白什么意思呢。今天发现都是同样的问题,哈哈:D
http://www.blogjava.net/iamtin/archive/2006/06/06/50702.html  回复  更多评论
  
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
2006-06-06 22:06 | 莫多
是啊。都是这个问题,不过Robbin给出了最终解决方法。呵呵。
http://www.javaeye.com/display/opensourceframework/HibernateUtils
可以看看。  回复  更多评论
  
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
2006-11-30 11:59 | guolp
哥们,当我 field.set(criteria,new ArrayList());
的时候,报错啊,提示不能修改private的成员
你是怎么解决的呢  回复  更多评论
  
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
2006-11-30 12:03 | 莫多[匿名]
field.set(criteria,new ArrayList());
这个是在做什么?  回复  更多评论
  
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
2006-11-30 12:03 | 莫多[匿名]
能详细说明的么?
  回复  更多评论
  
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
2006-12-22 15:36 | 陈亮
私有变量能这样子取 并 做修改?????????  回复  更多评论
  
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
2006-12-22 15:41 | 莫多[匿名]
@陈亮

是啊。java的反射嘛。
  回复  更多评论
  
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
2006-12-28 13:16 | BeanSoft
反射也要符合Java语言规范啊, 所以你这样是行不通的.  回复  更多评论
  
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
2006-12-28 13:19 | 莫多[匿名]
如何行不同呢?
  回复  更多评论
  
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
2008-06-20 16:41 | katelin
field.setAccessible(true);  回复  更多评论
  
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法[未登录]
2008-09-03 11:05 | nicholas
Criteria criteria = detachedCriteria
.getExecutableCriteria(openSession());
CriteriaImpl impl = (CriteriaImpl) criteria;
//Remove order clauses where query count.
//Order clause may cause some problem when we query count in some
//database.
//such as hsqldb.
List orderEntrys = new ArrayList();
try{
Field field = CriteriaImpl.class.getDeclaredField("orderEntries");
//field is private, so we must set it accessible when we access it.
field.setAccessible(true);
//Get orders
orderEntrys = (List) field.get(impl);
//Remove orders
field.set(criteria,new ArrayList());
}catch(Exception ex){
ex.printStackTrace();
}

int totalCount = ((Integer) criteria.setProjection(
Projections.rowCount()).uniqueResult()).intValue();
criteria.setProjection(null);
//add stored order clauses.
try{
Field field = CriteriaImpl.class.getDeclaredField("orderEntries");
field.setAccessible(true);
List innerOrderEntries = (List) field.get(criteria);
innerOrderEntries.addAll(orderEntrys);
}catch(Exception ex){
ex.printStackTrace();
}

List<T> items = criteria.setFirstResult(startIndex)
.setMaxResults(pageSize).list();  回复  更多评论
  
# re: 关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法
2009-07-14 10:36 | 聚资库
好东西!!  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 

<2008年6月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用链接

留言簿(1)

随笔分类(27)

随笔档案(22)

Friends

搜索

  •  

积分与排名

  • 积分 - 61384
  • 排名 - 847

最新评论

阅读排行榜

评论排行榜