You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实体开启@Cacheable二级缓存时,EntityManager.getReference()和find()有区别吗?

问题解答

二者行为不完全一致,即便实体B已经开启二级缓存,两者的核心逻辑和开销依然存在明显差异:

  • 核心逻辑差异
    • getReference() 本质是返回实体的懒加载代理对象,调用阶段不会触发任何查询动作:既不会查数据库,也不会主动查询二级缓存,只会基于你传入的主键生成代理实例。只有当你后续访问该代理的非主键字段时,才会依次查询一级缓存、二级缓存,缓存不命中才发起SQL查询。
    • find() 调用后会立刻触发全量查询逻辑:优先查当前持久上下文的一级缓存,再查二级缓存,都不命中才发起SQL查询数据库,返回的是已经完成初始化的实体对象,不是代理类型。
  • 适配你的场景的选择建议
    你当前的需求是更新关联了B的实体A,仅需要B的主键作为外键关联值,不需要访问B的其他字段,这种场景下哪怕B开了二级缓存,依然优先用getReference():
    1. 不会触发任何查询(包括缓存查询),完全没有额外开销
    2. 避免了find()方法带来的二级缓存查找、大实体反序列化的冗余开销
  • 容易踩坑的特殊情况
    如果你调用getReference()之后主动访问了B的非主键字段,此时才会触发二级缓存查询逻辑,返回的字段值和find()结果一致,但返回的对象本质还是代理类型,做instanceof之类的类型判断时要注意二者的差异。

内容的提问来源于stack exchange,提问作者Rey Libutan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 10:45:03