【问题】
- 当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 就是这样,不要忘了主表的排序哟。
相关推荐
HQL的灵活性在于它可以处理对象关系,例如一对一、一对多、多对多的关系。在SQL中,处理这些关系通常需要复杂的联接操作,而在HQL中则相对简单。此外,HQL支持动态查询,可以方便地处理集合类型的参数。 四、HQL的...
Hibernate Query Language(HQL)是Hibernate框架中用于操作对象关系映射(ORM)的一种查询语言。它是面向对象的,设计目的是让开发人员可以使用对象而不是数据库表进行查询,从而简化了与数据库交互的过程。HQL的...
- **关联查询**:处理一对多、一对一、多对多等关联关系的查询。 4. **条件查询** - 使用WHERE子句指定查询条件,支持比较操作符(=、<、>、、>=、!=)、逻辑操作符(AND、OR、NOT)以及IN、BETWEEN、LIKE等。 5...
通过使用FETCH JOIN,可以一次性加载关联对象或集合,避免了多次查询数据库的问题,提高了数据加载效率。 6. **SELECT子句**:HQL的SELECT子句用于指定查询结果中包含的对象或属性。例如,“SELECT mate FROM Cat”...
2. **关联关系**:List集合通常与数据库的一张表进行关联,通过外键字段建立一对一、一对多或多对多的关系。例如,一个学生可以有多个课程,这就是一对多的关系。 3. **索引**:List集合可以使用索引来指定每个元素...
1. 关联查询:HQL支持一对多、一对一、多对多关系的查询,如`from User u join u.addresses a where a.city='北京'`,查询所有城市为北京的用户及其地址。 2. 子查询:可以在HQL中嵌套查询,例如`select u from User...
4. **关联的处理**:HQL支持处理一对一、一对多、多对一和多对多的关联。例如,`from Cat as cat left join fetch cat.kittens as kittens`会加载每只猫及其所有幼崽,即使幼崽数据未被立即使用,也能通过父对象访问...
在提供的链接中,可以找到更多关于Hibernate一对多关联的实例和详细解释,包括如何在XML映射文件中配置这些关系。通过深入学习和实践,开发者能够熟练地在项目中运用Hibernate的一对多关联,提高开发效率和代码质量...
**HQL**(Hibernate Query Language)是Hibernate框架推荐使用的查询语言,它提供了一种面向对象的方式来查询数据库,支持多种复杂的查询操作,如继承、多态及关联关系的查询。 ##### 默认数据库表和数据 在本文档...
本文将深入探讨“Hibernate自身关联一对多实例(树形结构)”这一主题,这在构建具有层次结构的数据模型时尤其常见,例如组织结构、地区树或者商品分类等。 首先,我们需要理解Hibernate的核心概念。Hibernate允许...
同时,文档《Hibernate对象状态及一对多关联.doc》详细介绍了如何设置和管理一对多关联,这种关联在企业级应用中非常常见,例如一个用户可以有多个订单。 2. **一对一和多对多关联** 在《Hiberate一对一和多对多...
双向映射可以通过多对一、一对一、一对多关系来实现。 控件映射 Hibernate 的控件映射可以将一个对象的控件属性映射到数据库中。控件映射可以使用 Map 实现动态控件。 继承映射 Hibernate 的继承映射可以将一个...
- **解释**: 多表查询涉及表之间的关联关系,例如一对一、一对多和多对多关系。 ##### 1.4.2 表中的数据 - **解释**: 涉及的表包括`student`、`course`和`sc`等。 ##### 1.4.3 修改持久化类 - **示例**: ```java ...
6. **多对一(One-to-Many)和一对多(Many-to-One)关联** 这是两种常见的关联关系。在Hibernate中,通过`@ManyToOne`和`@OneToMany`注解可以定义这种关系。在联表查询时,可以通过这些注解实现数据的级联加载或...
例如,@OneToMany、@ManyToMany表示一对多或多对多关系,@ElementCollection用于映射基本类型的集合。 七、关联关系映射 关联关系包括一对一、一对多、多对一、多对多四种类型。在映射文件或注解中,需定义两侧的...
4. **关联查询**:HQL支持多表查询,可以处理一对一、一对多、多对一、多对多的关系。通过`join`关键字,可以进行内连接、外连接等操作,甚至可以进行子查询。 5. **动态查询**:Hibernate提供`Criteria` API和`...
10. **一对多、多对一、一对一和多对多关系映射**:Hibernate支持多种关联映射,包括集合映射,如List、Set、Map等,以及复合主键的处理。 11. **继承映射**:在Java中,子类可以继承父类。在Hibernate中,这种继承...
9. **集合映射**:在一对多关系中,Hibernate通常使用集合(List, Set, Bag等)来表示多个关联对象。集合类型的选择会影响到数据的唯一性和排序。 10. **外键约束**:在数据库中,关系映射往往涉及到外键约束,...