2010-09-21 63 views
1

请考虑以下具有两个ManyToOne引用的父类。HIbernate获取连接发出额外的SQL语句

@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" 

这总是导致休眠发出单独的SQL语句来加载,即使它才会在获取加入childInstance1行。

任何帮助避免额外的SQL语句表示赞赏。

回答

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 Anno t 3.4.0.GA.

+0

其实我发现问题...好像在你的测试中你忽略了引起问题的referencedColumnName。我正在引用一个非主键列。一旦我修改了referencedColmumnName作为子键的主键列,额外的sql语句就消失了。 – Sasi 2010-09-21 21:27:53

+0

@Sasi我没有忽略它,我使用了默认:)(因为我不知道FK_COLUMN_NAME是什么,因为我喜欢默认设置)。但是,如果您指定它,它确实是被引用表的PK列。 – 2010-09-21 21:36:53