禁用共享与查询缓存后EclipseLink PerformanceMonitor为何仍显示缓存命中
你配置的两个参数仅关闭了EclipseLink的二级共享缓存与全局默认查询结果缓存,并未关闭JPA规范强制要求的持久化上下文一级缓存,监控观测到的非零缓存命中计数全部来自一级缓存,属于框架正常行为。
配置作用范围说明
你当前添加的两个配置生效边界非常明确,不会影响一级缓存逻辑:
eclipselink.cache.shared.default=false:仅禁用跨EntityManager、跨事务共享的二级对象缓存,对单个持久化上下文范围内的实体缓存无任何作用eclipselink.query-results-cache=false:仅禁用跨查询复用结果集的全局查询缓存,不干预持久化上下文内的托管实体复用逻辑
监控计数逻辑
PerformanceMonitor的CacheHits系列计数器统计所有缓存层级的命中总次数,并非仅统计二级共享缓存的命中。只要查询执行时没有向数据库发送SQL、直接从任意缓存层拿到了可用结果,就会累加对应计数器的数值。
你日志中出现的Counter:ReadObjectQuery:mine.data.impl.DataImpl:item:CacheHits 8条目是典型的一级缓存命中场景:在同一个EntityManager/同一个事务的持久化上下文生命周期内,多次读取同一个主键标识的DataImpl实体时(包括主动调用find方法、遍历实体关联关系、执行查询返回已处于托管状态的实体等场景),EclipseLink会直接返回当前上下文中已经存在的托管实体实例,不会重复查询数据库,这个实例复用过程就会被记录为缓存命中。
补充说明
EclipseLink的一级缓存是JPA规范明确要求的默认行为,核心作用是保证同一个持久化上下文内,同一条数据库记录对应唯一的实体实例,以此维护实体的托管状态、脏检查等核心机制,该缓存无法通过你配置的两个参数关闭。
如果要消除这类一级缓存命中,只能在两次查询之间调用EntityManager.clear()清空整个持久化上下文、调用detach方法移除指定实体的托管状态,或是每次数据操作都使用全新的EntityManager实例。这类操作会破坏JPA的实体状态管理逻辑,非特殊业务场景不建议使用。
内容的提问来源于stack exchange,提问作者Neel

