ManyToOne double select hibernate



我有一个Parent表,一个id字段作为PK,一个Child表有自己的id字段作为PK,一个parent_id列引用Parent表中的id作为FK。

假设我的Parent表中有4个id,Child表中有4行,如下所示:

| id | parent_id |
1      1
2      2
3      3
4      3

可以看到,值为'4'的Parentid没有子节点。

Parent表的映射是一个带有单个字段的简单pojo,Child实体的映射是这样的:

@Entity
@Table(name = "child")
public class Child {
@Id
@Column
private Integer id;

@ManyToOne
private Parent parent;

// getters & setters
}

从java代码中,我运行这个查询:

TypedQuery<Child> practicesQuery = dataBaseContext.getCurrentSession().createQuery(""
+ "FROM Child c WHERE c.parent.id = :id", Child.class).setParameter("id", id);
return practicesQuery.getResultList();

我试着为前3个id运行它,hibernate为每个"fetch"生成2个select语句。像这样的操作:

Hibernate: 
select
child0_.id as id1_59_,
child0_.parent_id as parent_i3_59_ 
from
child child0_ 
where
child0_.parent_id=?
Hibernate: 
select
parent0_.id as id1_111_0_ 
from
parent parent0_ 
where
parent0_.id=?

,但是当我对id = 4运行相同的查询时,只执行第一个查询。

为什么hibernate试图获得那些有一些孩子(id 1,2和3)的父母,但不为没有孩子(id 4)的父母执行select语句?当然,在这种情况下,第二次选择总是无用的。

谢谢

@ManyToOne关系的默认抓取策略是EAGER。由于您使用的是父文件的默认获取策略,Hibernate将触发父表上的第二个查询来加载父记录。

在JPA规范中,@ManyToOne关系的默认获取类型是

public abstract FetchType fetch
(Optional) Whether the association should be lazily loaded or must be eagerly fetched. The EAGER strategy is a requirement on the persistence provider runtime that the associated entity must be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime.
Default:
javax.persistence.FetchType.EAGER

如果你不想急切地加载父对象,将获取类型设置为lazy

@Entity
@Table(name = "child")
public class Child {
@Id
@Column
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
private Parent parent;
}

最新更新