【问题标题】:HIbernate fetch join issuing additional sql statementsHIbernate fetch join 发出额外的 sql 语句
【发布时间】:2011-04-15 09:57:10
【问题描述】:

考虑以下具有两个 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 语句。

【问题讨论】:

    标签: java hibernate orm fetching-strategy


    【解决方案1】:

    我无法复制。给定以下实体:

    @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 一起正常工作。

    【讨论】:

    • 实际上我发现了这个问题......似乎在你的测试中你忽略了导致问题的referencedColumnName。我正在引用一个非主键列。一旦我将 referencedColmumnName 修改为子项的主键列,额外的 sql 语句就消失了。
    • @Sasi 我没有忽略它,我使用了默认值:)(因为我不知道 FK_COLUMN_NAME 是什么,而且我喜欢默认值)。但是如果你指定它,它确实必须是被引用表的PK列。
    猜你喜欢
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多