`

通过hql控制hibernate一对多的集合属性的排序

阅读更多

【问题】

  • 当hibernate实体中存在一对多关系集合时(比如:Person 1->* Addr ) ,无法完全使用hql来控制集合属性内部的排序。
  • 假设我们想addrs集合按照addr.id排序,理所当然的想到硬编码@OrderBy("id"),可是这样的话无论hql中是否已经有orderby语句,最后都会追加一句orderby addrs.id,这样在一些我们不想将addrs按照id排序的场景下就会有问题(hibernate并不会检测你是否在hql定制了排序,始终默认添加),这不是我们想要的
  • 但是如果不加@OrderBy("id"),那么产生的集合底层是hashset(不要问我怎么知道的都是泪= =。 调试了好久,其实一开始就应该想到)

 【具体解决问题的过程】

  • 首先想确定到底是不是hibernate底层返回的顺序就是不对的(因为当时没去看返回的PersistCollection的私有变量 = =,如果看了的话,就可以跳过下面的很大一部分解析过程)。看query,一路追查到 org.hibernate.loader.Loader.readCollectionElement,发现有日志可以打(log4j.logger.org.hibernate.loader=DEBUG),开启后可以清楚看到hibernate读取每一行的过程,同时也得到结论,读取的时候顺序是按照我hql的排序规则,没问题。
  • 在以上调试过程中发现org.hibernate.mapping.Set.getDefaultCollectionType 方法 
    public class Set extends Collection {
    
    public CollectionType getDefaultCollectionType() {
    		if ( isSorted() ) {
    			return TypeFactory.sortedSet( getRole(), getReferencedPropertyName(), isEmbedded(), getComparator() );
    		}
    		else if ( hasOrder() ) {
    			return TypeFactory.orderedSet( getRole(), getReferencedPropertyName(), isEmbedded() );
    		}
    		else {
    			return TypeFactory.set( getRole(), getReferencedPropertyName(), isEmbedded() );
    		}
    	}
    
    //...以下是集成父类Collection中的方法
    public boolean hasOrder() {
    		return orderBy!=null || manyToManyOrderBy!=null;
    	}
    }
     好像瞬间明白了些什么。。没错,就是直接写@orderby注解就是linkedhashset了,这样就能保证数集合类根据hql的规则,也就是实际返回数据的顺序来进行排序。。唉好坑~最终解决方法实在是太简单了,绕了一大圈。 

【结论以及解决方法】

  • @Entity
    @Table(name = "...")
    public class Person{
    
    @OneToMany(mappedBy = "person")
    @OrderBy //***没错就是这行,只写注解,不写参数!!!***
    public Set<Addr> getAddrs() {
    return addrs;
    }
    
    }
      

 PS: 大家可能要问这样排序好像不对吧!没错,我省略了主表的排序语句,这个大家记得自己补上吧,举例就是 select p from Persion p left join fetch p.addrs a order by p.id,a.id  就是这样,不要忘了主表的排序哟。

 

分享到:
评论

相关推荐

    Hibernate+中文文档

    7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...

    HibernateAPI中文版.chm

    7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...

    hibernate3.2中文文档(chm格式)

    7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     15.3.4 把多对多关联分解为两个一对多关联  15.4 小结  15.5 思考题 第16章 Hibernate的检索策略  16.1 Hibernate的检索策略简介  16.2 类级别的检索策略  16.2.1 立即检索  16.2.2 延迟检索  16.3 一对多...

    Hibernate中文详细学习文档

    7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...

    Hibernate 中文 html 帮助文档

    7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...

    hibernate 体系结构与配置 参考文档(html)

    一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在...

    Hibernate教程

    8.4.1. 一对多(one to many) / 多对一(many to one) 8.4.2. 一对一(one to one) 8.5. 使用连接表的双向关联(Bidirectional associations with join tables) 8.5.1. 一对多(one to many) /多对一( many ...

    最全Hibernate 参考文档

    7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在集合中出现的依赖对象 ...

    Hibernate实战(第2版 中文高清版)

     7.2.1 一对多关联   7.2.2 多对多关联   7.2.3 把列添加到联结表   7.2.4 映射map   7.3 多态关联   7.3.1 多态的多对一关联   7.3.2 多态集合   7.3.3 对联合的多态关联   7.3.4 每个具体类一张...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     15.3.4 把多对多关联分解为两个一对多关联  15.4 小结  15.5 思考题 第16章 Hibernate的检索策略  16.1 Hibernate的检索策略简介  16.2 类级别的检索策略  16.2.1 立即检索  16.2.2 延迟检索  16.3 一对多...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     15.3.4 把多对多关联分解为两个一对多关联  15.4 小结  15.5 思考题 第16章 Hibernate的检索策略  16.1 Hibernate的检索策略简介  16.2 类级别的检索策略  16.2.1 立即检索  16.2.2 延迟检索  16.3 一对多...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     15.3.4 把多对多关联分解为两个一对多关联  15.4 小结  15.5 思考题 第16章 Hibernate的检索策略  16.1 Hibernate的检索策略简介  16.2 类级别的检索策略  16.2.1 立即检索  16.2.2 延迟检索  16.3 一对多...

    hibernate 教程

    一对多关联(One-To-Many Associations) 6.5. 延迟初始化(延迟加载)(Lazy Initialization) 6.6. 集合排序(Sorted Collections) 6.7. 使用&lt;idbag&gt;&lt;br&gt;6.8. 双向关联(Bidirectional Associations)...

    hibernate3.04中文文档.chm

    8.5.1. 一对多(one to many) /多对一( many to one) 8.5.2. 一对一(one to one) 8.5.3. 多对多(many to many) 9. 组件(Component)映射 9.1. 依赖对象(Dependent objects) 9.2. 在集合中出现的依赖...

    hibernate 框架详解

    一对多(one to many) /多对一( many to one) 8.5.2. 一对一(one to one) 8.5.3. 多对多(many to many) 9. 组件(Component)映射 9.1. 依赖对象(Dependent objects) 9.2. 在集合中出现的依赖对象 ...

    Hibernate3+中文参考文档

    7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在集合中出现的依赖对象 ...

    Hibernate参考文档

    7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在...

Global site tag (gtag.js) - Google Analytics