Hibernate使用Projection时一级缓存的工作机制及有效性疑问
先给你把这个事儿说透:Hibernate的一级缓存(也就是Session级缓存)本质是完整实体实例的缓存容器,它的核心逻辑是通过实体的ID来识别和存储对象——只有当你操作的是Hibernate映射过的完整实体时,这个缓存才会工作。那用Projection的时候情况就得分两种来看:
如果Projection返回的不是完整实体(比如只查几个字段、返回DTO/Object数组,甚至没包含实体ID):
这种情况下,一级缓存完全不会介入。因为缓存只认它管理的实体对象,而投影出来的是零散的数据或者自定义的非实体对象,Hibernate不会把这些东西放到Session缓存里。举个例子,你写个HQL用Projections.property("user.name")和Projections.property("order.amount")关联三张表查出来的姓名和金额,得到的结果数组根本不会碰一级缓存,缓存该干嘛还是干嘛,但和这些投影结果没关系。如果Projection查询中包含完整实体(同时带ID):
比如你用Projections.entity(User.class)加上其他投影字段,这时候Hibernate会把查询到的User实体实例正常存入一级缓存,但那些额外的投影字段或者组合结果依然不会被缓存——缓存只负责实体本身,不管你额外查了啥。
所以你问的“使用Projection时一级缓存是否失效”?其实不是失效,而是一级缓存本来就不作用于投影结果。它仍然会正常缓存那些被查询到的完整实体,但投影出来的非实体数据不在它的管辖范围内。简单说:一级缓存管的是“实体对象”,Projection如果不返回实体,就和它没交集。
内容的提问来源于stack exchange,提问作者Ankit Bansal

