使用EclipseLink JPA查询实体如何仅获取外键字符串ID不加载关联实体
可行方案
这里提供3种常用的实现方式,都可以避免多余的关联表查询:
方案1:新增只读外键映射字段(最直观通用)
直接在MyEntity实体中新增一个映射到外键列的只读字段,和现有@OneToOne关联共享同一列,不会产生冲突也不需要修改原有业务逻辑:
@Entity @Table(name = "myentity") // 省略原有注解 public class MyEntity { // 省略原有字段 @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "my_foreign_key", referencedColumnName = "external_pk") private AnotherEntity anotherEntity; // 新增只读外键字段,标记为不可插入不可更新,避免和关联注解的列映射冲突 @Column(name = "my_foreign_key", insertable = false, updatable = false) private String myForeignKey; }
后续直接调用getMyForeignKey()就能拿到外键值,完全不需要触发AnotherEntity的加载查询。
方案2:修改关联为懒加载+直接取代理主键
@OneToOne默认是FetchType.EAGER立即加载,这是触发二次查询的核心原因之一,你可以将关联改为懒加载:
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "my_foreign_key", referencedColumnName = "external_pk") private AnotherEntity anotherEntity;
EclipseLink的懒加载ToOne关联会自动缓存外键值到代理对象中,此时你只要不访问AnotherEntity的非主键字段,就不会触发二次查询:
- 调用
myEntity.getAnotherEntity()拿到的是代理对象,不会触发查询 - 调用
myEntity.getAnotherEntity().getExternalPk()直接返回缓存的外键值,不会触发查询 - 只有调用
getSomething()等非主键方法时才会触发关联表查询
方案3:查询时直接投影外键值
如果你只需要外键值不需要完整的MyEntity实体,可以直接在JPQL/Criteria查询中指定投影,EclipseLink会直接读取myentity表的外键列,不会关联查询:
// JPQL示例,直接取关联实体主键,不需要JOIN TypedQuery<String> query = em.createQuery( "SELECT e.anotherEntity.externalPk FROM MyEntity e WHERE e.foo = :foo", String.class ); query.setParameter("foo", "testValue"); String foreignKey = query.getSingleResult();
这种方式甚至不需要修改实体定义,仅在需要单独取外键的查询场景使用即可。
内容的提问来源于stack exchange,提问作者payne
相关产品推荐
相关产品推荐

