HIbernate fetch join 发出额外的 sql 语句

发布于 2024-09-24 01:53:35 字数 1078 浏览 7 评论 0原文

考虑以下具有两个 ManyToOne 引用的 Parent 类。

@Entity
@Table(name = "PARENT")
public class Parent {

private static final long serialVersionUID = 3730163805206219313L;

@Id
@SequenceGenerator(name = "SEQ#PARENT", sequenceName = "SEQ#PARENT", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ#PARENT")
@Column(name = "ID")
private long id;

@ManyToOne(optional = false, fetch=FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name="CHILD_1_ID", referencedColumnName="FK_COLUMN_NAME")
private Child childInstance1;

@ManyToOne(optional = false, fetch=FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name="CHILD_2_ID", referencedColumnName="FK_COLUMN_NAME")
private Child childInstance2;

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

我正在使用以下 hql 查询来加载父实例:

"from Parent p  join fetch p.childInstance1 join fetch p.childInstance2 where p.userId = :userId"

这总是导致 hibernate 发出单独的 sql 语句来加载 childInstance1 行,即使它执行了 fetch join。

任何避免额外 sql 语句的帮助都是值得赞赏的。

Consider the following Parent class that has two ManyToOne references.

@Entity
@Table(name = "PARENT")
public class Parent {

private static final long serialVersionUID = 3730163805206219313L;

@Id
@SequenceGenerator(name = "SEQ#PARENT", sequenceName = "SEQ#PARENT", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ#PARENT")
@Column(name = "ID")
private long id;

@ManyToOne(optional = false, fetch=FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name="CHILD_1_ID", referencedColumnName="FK_COLUMN_NAME")
private Child childInstance1;

@ManyToOne(optional = false, fetch=FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name="CHILD_2_ID", referencedColumnName="FK_COLUMN_NAME")
private Child childInstance2;

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

I am using the following hql query to load the Parent instance:

"from Parent p  join fetch p.childInstance1 join fetch p.childInstance2 where p.userId = :userId"

This always results in hibernate issuing separate sql statements to load the childInstance1 rows even though it does the fetch join.

Any help in avoiding the extra sql statements is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

在梵高的星空下 2024-10-01 01:53:35

我无法重现。给定以下实体:

@Entity
public class Parent3764122 {
    @Id @GeneratedValue
    private long id;

    @ManyToOne(optional = false/*, fetch=FetchType.EAGER*/) // EAGER by default
    //@Fetch(FetchMode.JOIN) // unnecessary
    @JoinColumn(name="CHILD_1_ID")
    private Child3764122 childInstance1;

    @ManyToOne(optional = false/*, fetch=FetchType.EAGER*/) // EAGER by default
    //@Fetch(FetchMode.JOIN) // unnecessary
    @JoinColumn(name="CHILD_2_ID")
    private Child3764122 childInstance2;

    @Column(name = "USER_ID")
    private String userId;
    ...
}

以及

@Entity
public class Child3764122 {
    @Id @GeneratedValue
    private Long id;

    ...
}

以下 HQL 查询:

from Parent3764122 p join fetch p.childInstance1 join fetch p.childInstance2 where p.id = :id

生成以下 SQL:

select
    parent3764x0_.id as id129_0_,
    child37641x1_.id as id130_1_,
    child37641x2_.id as id130_2_,
    parent3764x0_.CHILD_1_ID as CHILD3_129_0_,
    parent3764x0_.CHILD_2_ID as CHILD4_129_0_,
    parent3764x0_.USER_ID as USER2_129_0_ 
from
    Parent3764122 parent3764x0_ 
inner join
    Child3764122 child37641x1_ 
        on parent3764x0_.CHILD_1_ID=child37641x1_.id 
inner join
    Child3764122 child37641x2_ 
        on parent3764x0_.CHILD_2_ID=child37641x2_.id 
where
    parent3764x0_.id=?

在 Hibernate 3.3.0.SP1、Hibernate Annotations 3.4.0.GA 中按预期工作。

I cannot reproduce. Given the following entities:

@Entity
public class Parent3764122 {
    @Id @GeneratedValue
    private long id;

    @ManyToOne(optional = false/*, fetch=FetchType.EAGER*/) // EAGER by default
    //@Fetch(FetchMode.JOIN) // unnecessary
    @JoinColumn(name="CHILD_1_ID")
    private Child3764122 childInstance1;

    @ManyToOne(optional = false/*, fetch=FetchType.EAGER*/) // EAGER by default
    //@Fetch(FetchMode.JOIN) // unnecessary
    @JoinColumn(name="CHILD_2_ID")
    private Child3764122 childInstance2;

    @Column(name = "USER_ID")
    private String userId;
    ...
}

and

@Entity
public class Child3764122 {
    @Id @GeneratedValue
    private Long id;

    ...
}

The following HQL query:

from Parent3764122 p join fetch p.childInstance1 join fetch p.childInstance2 where p.id = :id

Generates the following SQL:

select
    parent3764x0_.id as id129_0_,
    child37641x1_.id as id130_1_,
    child37641x2_.id as id130_2_,
    parent3764x0_.CHILD_1_ID as CHILD3_129_0_,
    parent3764x0_.CHILD_2_ID as CHILD4_129_0_,
    parent3764x0_.USER_ID as USER2_129_0_ 
from
    Parent3764122 parent3764x0_ 
inner join
    Child3764122 child37641x1_ 
        on parent3764x0_.CHILD_1_ID=child37641x1_.id 
inner join
    Child3764122 child37641x2_ 
        on parent3764x0_.CHILD_2_ID=child37641x2_.id 
where
    parent3764x0_.id=?

Works as expected with Hibernate 3.3.0.SP1, Hibernate Annotations 3.4.0.GA.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文