Hibernate中两条相同JPQL查询为何返回不同结果计数?
相同JPQL查询返回结果数量差异的原因
你编写了两条结构完全一致的JPQL查询,分别用Object[]和Library作为结果类型,但返回的结果数量不同:前者返回5条,后者仅返回3条。相关代码和数据库数据如下:
代码示例
String jpqlWithObjectType = """ SELECT l FROM Library l JOIN Member m ON m.library.id = l.id """; TypedQuery<Object[]> query1 = entityManager.createQuery(jpqlWithObjectType, Object[].class); List<Object[]> libraries = query1.getResultList(); System.out.println(libraries.size()); // 输出5 String jpqlWithLibraryType = """ SELECT l FROM Library l JOIN Member m ON m.library.id = l.id """; TypedQuery<Library> query2 = entityManager.createQuery(jpqlWithLibraryType, Library.class); List<Library> libraries3 = query2.getResultList(); System.out.println(libraries3.size()); // 输出3
数据库数据
INSERT INTO Library (id, name, location, establishedDate) VALUES (1, 'Central Library', 'Downtown', '1990-03-15'), (2, 'West End Library', 'West City', '1985-07-20'), (3, 'East Side Library', 'East City', '2000-09-05'); INSERT INTO Member (id, first_name, last_name, email, location, library_id) VALUES (1, 'Alice', 'Johnson', 'alice.johnson@example.com', 'Downtown', 1), (2, 'Bob', 'Smith', 'bob.smith@example.com', 'West City', 2), (3, 'Charlie', 'Brown', 'charlie.brown@example.com', 'East City', 3), (4, 'Diana', 'Prince', 'diana.prince@example.com', 'Downtown', 1), (5, 'Eve', 'Adams', 'eve.adams@example.com', 'East City', 3);
原因解释
1. 数据库层面的查询结果
两条JPQL最终生成的SQL完全相同,执行后数据库会返回5条记录:每个Member关联一个Library,因此Library1出现2次、Library2出现1次、Library3出现2次,总共5行数据。
2. Object[]类型查询的行为
当用Object[]作为结果类型时,Hibernate仅将数据库返回的每一行数据直接封装为对象数组,不会对结果做额外处理。因此List会完整保留这5条包含重复Library数据的数组,最终结果数量为5。
3. Library实体类型查询的行为
当查询目标是实体类型(Library.class)时,Hibernate会通过**持久化上下文(一级缓存)**管理实体实例:
- 加载第一条Library1记录时,会将该实例存入缓存;
- 后续遇到相同id的Library1记录时,不会创建新实例,直接返回缓存中已存在的对象;
- Library3的重复记录也会遵循同样的缓存去重逻辑。
最终List中只会保留3个唯一的Library实体实例,因此结果数量为3。
额外说明
如果想要让实体类型查询也返回5条包含重复的结果,需要绕过Hibernate的实体缓存机制,比如改用原生SQL查询并手动映射结果,或者使用SELECT NEW语法返回自定义DTO(而非实体类),这样Hibernate不会对结果进行去重处理。
内容的提问来源于stack exchange,提问作者Hamza Nasir
相关产品推荐
相关产品推荐

