2011-08-01 7 views
6

J'ai une méthode de service Hibernate en tant que telle: "SELECT sc FROM SecurityContact sc WHERE sc.securityId=:securityId2". securityId2 est transmis par l'utilisateur. Chaque SecurityContact a une relation plusieurs à un avec un contact, Hibernate appelle automatiquement une jointure lorsque cette requête s'exécute. Cependant, la jointure que Hibernate exécute toujours est une jointure interne qui ne fonctionnera pas correctement pour mes besoins. Est-il possible de forcer Hibernate à générer une jointure externe gauche à la place? Voici le code pour la classe SecurityContact:Hibernate Left Outer Join

/** 
* The persistent class for the SecurityContact database table. 
* 
*/ 
@Entity 
@FXClass(kind=FXClassKind.REMOTE) 
public class SecurityContact implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Transient private String uid; 
    @FXIgnore 
    public String getUid() { 
     if (uid == null) { 
      uid = "" + securityContactId; 
     } 
     return uid; 
    } 

    public void setUid(String uid) { 
     this.uid = uid; 
    } 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="securityContact_id") 
    private Long securityContactId; 

    @Column(name="security_id") 
    private String securityId; 

    @Column(name="create_date") 
    private String createDate; 

    @Column(name="create_user") 
    private String createUser; 

    @Column(name="modify_date") 
    private String modifyDate; 

    @Column(name="modify_user") 
    private String modifyUser; 

    //bi-directional many-to-one association to AgentContact 

    @ManyToOne 
    @JoinColumn(name="agent_id", referencedColumnName="contact_id") 
    private AgentContact agentContact; 

    //bi-directional many-to-one association to AuditContact 
    @ManyToOne 
    @JoinColumn(name="audit_id", referencedColumnName="contact_id") 
    private AgentContact auditContact; 

    public SecurityContact() { 
    } 
    @FXKeyColumn 
    public Long getSecurityContactId() { 
     return this.securityContactId; 
    } 

    public void setSecurityContactId(Long securityContactId) { 
     this.securityContactId = securityContactId; 
    } 

    public String getSecurityId() { 
     return this.securityId; 
    } 

    public void setSecurityId(String securityId) { 
     this.securityId = securityId; 
    } 

    public String getCreateDate() { 
     return this.createDate; 
    } 

    public void setCreateDate(String createDate) { 
     this.createDate = createDate; 
    } 

    public String getCreateUser() { 
     return this.createUser; 
    } 

    public void setCreateUser(String createUser) { 
     this.createUser = createUser; 
    } 

    public String getModifyDate() { 
     return this.modifyDate; 
    } 

    public void setModifyDate(String modifyDate) { 
     this.modifyDate = modifyDate; 
    } 

    public String getModifyUser() { 
     return this.modifyUser; 
    } 

    public void setModifyUser(String modifyUser) { 
     this.modifyUser = modifyUser; 
    } 
    @FXManyToOne(parent="parent", property="contactId") 
    public AgentContact getAgentContact() { 
     return this.agentContact; 
    } 

    public void setAgentContact(AgentContact agentContact) { 
     this.agentContact = agentContact; 
    } 
    @FXManyToOne(parent="parent", property="contactId") 
    public AgentContact getAuditContact() { 
     return this.auditContact; 
    } 

    public void setAuditContact(AgentContact auditContact) { 
     this.auditContact = auditContact; 
    } 

} 
+0

Pouvez-vous poster votre fichier de correspondance ou des annotations? – dfb

Répondre

2
+0

Voulez-vous inclure l'annotation @Fetch (FetchMode.SELECT)? –

+0

Oui - c'est l'annotation équivalente du XML dans les documents que je mets là. – dfb

+0

Désolé pour la question stupide, mais juste pour être sûr, où exactement dans le segment de code fourni je placerais cette annotation? –

0

Dans vos configs mise en veille prolongée définissez la propriété use_outer_join true.

+0

Cela n'a apparemment pas eu d'effet. –

1

Selon la documentation d'Hibernate, le langage de requête d'hibernation devrait le supporter. (Au moins dans la version 3,3)

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html#queryhql-joins

Essayez de créer votre requête comme ceci:

Query query = entityManager.createQuery("Select sc from SecurityContact as sc " + 
             "left outer join sc.agentContact as c " + 
             "where sc.securityId=:securityId2"; 

EDIT: Modification de la propriété de contact de sc à la propriété agentContact que vous avez fourni vos coordonnées question.

+0

Avec ma requête définie comme: "SELECT sc FROM SecurityContact sc LEFT OUTER JOIN sc.agentContact ac WHERE sc.securityId =: securityId2", cela ne semble pas fonctionner. –

+0

Pouvez-vous essayer d'ajouter un ac à la sélection: "SELECT sc, ac DE SecurityContact sc LEFT OUTER JOIN sc.agentContact ac WHERE sc.securityId =: securityId2". Le résultat sera un tableau d'objets avec les résultats. – david

+0

Hibernate n'aime pas cette requête pour une raison quelconque. Il jette des erreurs lors de la recompilation. –

1

Relation: compte beaucoup - employé un

la configuration xml:

 <many-to-one name="employee" class="active.security.domain.Employee" lazy="false"> 
     <column name="EmpId" /> 
    </many-to-one> 

code java:

 Session session = HibernateUtil.getCurrentSession(); 

    Criteria criteria = session.createCriteria(Account.class); 
    criteria.add(Restrictions.eq("application.id", applicationID)); 
    List<Account> list = criteria.list(); 

la clé est d'utiliser criteria.list();

0

J'ai eu la configuration suivante:

<many-to-one column="user_id" lazy="proxy" fetch="join" insert="false" name="user" not-null="true" update="false" not-found="ignore" /> 

La colonne user_id n'a pas été nulle, mais je voulais un LEFT OUTER JOIN (au lieu de INNER JOIN je devenais), parce qu'il était juste un hack DB - parfois user_id = 0 qui n'a été mappé à aucune ligne de la table utilisateur (0 en remplacement de NULL). Je ne voulais pas le mode fetch=select

Après beaucoup de débogage dans les intervalles Hibernate je not-null="false" ensemble qui a résolu le problème pour moi :) (je suis le LEFT OUTER JOIN). Espérons que quelqu'un le trouvera utile (btw.: J'utilise Hibernate 3.6.0.Final).

0

J'ai eu un problème similaire. J'avais un DAO SiebelUser. Chaque SiebelUser lié à une équipe avec plusieurs à une relation. Certains SiebelUser avaient userid = 0 comme clé étrangère pour laquelle aucune clé primaire n'était présente dans la table Users. Donc, naturellement, le fetch de la table SeibelUsers ignorait les utilisateurs avec userd id = 0. Cette configuration a été précédemment

<many-to-one name="teamid" class="com.hewitt.wlm.pojo.Tblteams"> <column name="TEAMID" length="4" not-null="true" /> </many-to-one>

Ainsi, Afin de résoudre mon problème j'ai changé la config. Mais ça n'a pas marché pour moi.

<many-to-one name="teamid" class="com.hewitt.wlm.pojo.Tblteams" **fetch="join" not-null="false" lazy="proxy" not-found="ignore"**> <column name="TEAMID" length="4" not-null="**false**" /> </many-to-one>

Enfin j'ai changé ma requête pour faire explicitement une jointure externe gauche comme celui-ci donnant le chemin specifc de SiebelUsers à la table des utilisateurs.

select property1, property2, ... 
from from **SiebelUser s left outer join s.team t** 
where property1='x' 

Cela a fonctionné pour moi.

Notez que ma classe SiebelUser avait l'objet Team comme sa propriété (comme défini dans le chemin ci-dessus). J'espère que cela aidera quelqu'un.