2010-09-21 3 views
1

Considérons la classe parent suivante qui a deux références ManyToOne.HIbernate fetch jointure émettant des instructions sql supplémentaires

@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;    
} 

J'utilise la requête HQL suivante pour charger l'instance parent:

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

Il en résulte toujours en veille prolongée émettant des instructions SQL séparées pour charger les lignes childInstance1 même si elle ne le fetch JOIN.

Toute aide pour éviter les instructions sql supplémentaires est appréciée.

Répondre

1

Je ne peux pas reproduire. Étant donné les entités suivantes:

@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; 
    ... 
} 

et

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

    ... 
} 

La requête HQL suivante:

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

Génère l'instruction SQL suivante:

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=? 

fonctionne comme prévu avec Hibernate 3.3 .0.SP1, Hibernate Anno tions 3.4.0.GA.

+0

En fait, j'ai trouvé le problème ... il semble que dans votre test, vous avez ignoré la referenceColumnName qui causait le problème. Je référençais une colonne de clé non primaire. Une fois que j'ai modifié la référenceColmumnName à la colonne de la clé primaire de l'enfant, les instructions sql supplémentaires ont disparu. – Sasi

+0

@Sasi Je ne l'ai pas ignoré, j'ai utilisé la valeur par défaut :) (parce que je n'avais aucune idée de ce que FK_COLUMN_NAME était et parce que j'aime les valeurs par défaut). Mais si vous le spécifiez, il doit s'agir de la colonne PK de la table référencée. –

Questions connexes