如何防止 Hibernate 在仅访问外键 ID 时获取已加入的实体?

2022-09-04 04:03:37

我有一个休眠实体,它连接到另一个:.在数据库中,我有一列对 具有外键约束。假设我正在懒惰地加载,当我加载一个实例时,我希望能够访问而不会在表上产生查找。ParentChildparent.child_idchild.idParentparent.getChild().getId()child

我期望返回的代理能够满足请求,因为它已经从列中加载了子项的id。但是,我在表上看到一个附加查询。parent.getChild()Child.getId()parent.child_idchild

为什么需要此额外查询,如何避免?在这个例子中,我只对外键ID感兴趣,不希望加载整行。

类:

class Parent {
  @Id @Column(name = "id", unique = true, nullable = false)
  private Integer id;

  @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "child_id")
  private Child child;
}

class Child {
  @Id @Column(name = "id", unique = true, nullable = false)
  private Integer id;

  @Column(name = "name")
  private String name;
}

表:

CREATE TABLE child (
    id int PRIMARY KEY,
    name varchar(10)
);

CREATE TABLE parent (
    id int PRIMARY KEY,
    child_id int REFERENCES (child.id)
);

答案 1

这是由使用字段访问的事实引起的(因为注释被放置在字段上),因此当您调用其任何方法时,Hibernate只会初始化代理。Child

如果将批注移动到属性,它将按预期工作。

从 JPA 2.0(Hibernate 3.5)开始,您可以以细粒度的方式对其进行配置:

@Access(AccessType.FIELD) // Default is field access
class Child {
    private Integer id;

    @Column(name = "name")
    private String name;

    @Access(AccessType.PROPERTY) // Use property access for id
    @Id @Column(name = "id", unique = true, nullable = false)
    public Integer getId() { ... }

    ...   
}

答案 2

推荐