2011-08-02 2 views
1

다른 연락처와의 관계가 1 : 1 인 SecurityContact라는 테이블이 있습니다. 두 개의 연락처에 대한 조인 열이 있으며 그 중 하나는 agentContact이고 다른 하나는 auditContact입니다. 나는 다음과 같은 HQL 쿼리를 실행하려고 :LEFT JOIN을 무시하는 최대 절전 모드

SELECT sc FROM SecurityContact sc LEFT JOIN sc.agentContact ac LEFT JOIN sc.auditContact ac2 WHERE sc.securityId=:securityId2 

그러나, 최대 절전 모드 완전히 LEFT이 문을 가입 무시하고 내부 조인 활용 SQL을 생성하기 위해 진행된다. 이것은 내 목적에 전혀 부합하지 않는다. 행운을 빌어 주석 가져 오기 설정을 시도했습니다. 이 문제로 인해 2 일 이상 미친 듯이 날아갔습니다. 그래서 어떤 도움이라도 대단히 감사 할 것입니다.

다음
/** 
* 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; 

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

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

    //uni-directional many-to-one association to AuditContact 
    @ManyToOne 
    @JoinColumn(name="audit_id", referencedColumnName="contact_id") 
    private Contact 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 Contact getAgentContact() { 
     return this.agentContact; 
    } 

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

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

} 

위의 HQL에서 생성 된 SQL입니다 :

select securityco0_.agent_id as col_0_0_, securityco0_.audit_id as col_1_0_, securityco0_.create_date as col_2_0_, securityco0_.create_user as col_3_0_, securityco0_.modify_date as col_4_0_, securityco0_.modify_user as col_5_0_, securityco0_.securityContact_id as col_6_0_, securityco0_.security_id as col_7_0_, agentconta3_.contact_id as contact1_0_0_, agentconta4_.contact_id as contact1_0_1_, agentconta3_.bank_id as bank10_0_0_, agentconta3_.create_date as create2_0_0_, agentconta3_.create_user as create3_0_0_, agentconta3_.email as email0_0_, agentconta3_.fax as fax0_0_, agentconta3_.modify_date as modify6_0_0_, agentconta3_.modify_user as modify7_0_0_, agentconta3_.name as name0_0_, agentconta3_.phone as phone0_0_, agentconta4_.bank_id as bank10_0_1_, agentconta4_.create_date as create2_0_1_, agentconta4_.create_user as create3_0_1_, agentconta4_.email as email0_1_, agentconta4_.fax as fax0_1_, agentconta4_.modify_date as modify6_0_1_, agentconta4_.modify_user as modify7_0_1_, agentconta4_.name as name0_1_, agentconta4_.phone as phone0_1_ from SecurityContact securityco0_ left outer join AgentContact agentconta1_ on securityco0_.agent_id=agentconta1_.contact_id left outer join AgentContact agentconta2_ on securityco0_.audit_id=agentconta2_.contact_id inner join AgentContact agentconta3_ on securityco0_.agent_id=agentconta3_.contact_id inner join AgentContact agentconta4_ on securityco0_.audit_id=agentconta4_.contact_id where securityco0_.security_id=? 
+0

하이버 네이트가 여기에서 왼쪽 조인을 사용하는 것이 왜 중요한가? 어떤 질문을 HQL 쿼리로 대답하려고합니까? 'securityId = securityId'에서 단순한''SecurityContact''와는 어떤 결과가 기대 되나요? –

+0

@matt 사용 가능한 해당 agentContact 나 auditContact가없는 경우에도 Hibernate가 항목을 반환하기를 원하므로 중요합니다. 그것은 내부 조인으로 그렇게하지 않을 것입니다. –

+0

하지만 기본적으로'@ ManyToOne' 연관은 선택적/null 가능하지 않습니까? 이 관계의 반대면은 다른 반에서 어떤 모양입니까? 간단한'session.get (SecurityContact.class, securityId)'가 두 필드 중 하나가 null 인 인스턴스를 반환하지 않는다고 말하는가? –

답변

1

나는 당신의 문제에 관해서 몇 가지 테스트를 수행했습니다, 그리고 당신이 당신의 매핑에 문제가 있거나 당신이 최대 절전 모드의 (오래된) 버전의 버그 중 하나가 있어야 날 것으로 보인다 사용. 옵션 @ManyToOne 협회

는 최대 절전 모드 이미 개체를 쿼리 왼쪽 조인 사용되어야하며, (가 연관된 엔티티가 null 여부 루트 개체를 쿼리 할 수있는 유일한 방법이기 때문에)는 협회입니다.

나는 이것을 https://github.com/mattnworb/hibernate-sample에 보여주는 샘플 프로젝트를 던졌다. 내 샘플 프로젝트에서

Employee 클래스는 a unidirectional many-to-one mapping to the Team class 있습니다 단위 테스트에서

/** 
* Unidirectional relationship between Employee and Team. 
*/ 
@ManyToOne 
@JoinColumn(name = "team_id") 
private Team team; 

, 테스트 모두가 그 DB 테이블에 그 Employee.teamis null when not set를 표명 Employee.team 참조 is not-null when it is set in the DB, 또 다른 시험 .

또한 비슷한 테스트를 통해 CompanyEmployee 엔티티간에 유사한 양방향 관계가 있습니다.

마지막으로, 로그에 내가 (간단한 session.get(Employee.class, id)과) 직원 실체에 대한 Hibernate 질의, 그것은 왼쪽을 사용하면 teams 테이블에 끌어 가입 것을 볼 수 있습니다 (I 추가 라인은 자신을 나누기) :

DEBUG org.hibernate.SQL이 - id1_2_로 employee0_.id 선택이 company6_1_2_로 employee0_.company_id, employee0_.dateOfBirth는 lastName1_2_로 dateOfBi2_1_2_, employme3_1_2_ 같은 employee0_.employmentStartDate, firstName1_2_ 같은 employee0_.firstName, employee0_.lastName로로 employee0_.team_id team7_1_2_, company1_.id를 id0_0_, company1_.name을 name0_0_, team2_.id를 id2_1_, team2_.name을 name2_1_
에서 emp loyees employee0_
왼쪽 외부 조인 회사 company1_ on employee0_.company_id = company1_.id
왼쪽 외부 조인 팀 team2_ on employee0_.team_id = team2_.id 여기서 employee0_.id =?간단한 session.get() - 모든 쿼리 Hibernate는 특별한 HQL 필요가 없을 것, 한 관계가 아니라 옵션 설정으로, 왼쪽을 사용하여 관련 기관 간의 조인하기 위해서는 그래서 합계에서

, 왜냐하면 루트 엔티티는 왼쪽 엔티티로 연관된 엔티티의 테이블을 쿼리해야하기 때문입니다. 다른 결과를 보았다면, 이것은 당신의 Hibernate 버전에 버그가있다 (나는 3.6.6.Final을 사용하고있다), 또는 당신의 매핑에 잘못된 것이 있다고 제안한다.

1

귀하의 HQL join syntax이 남았습니다 보이는 여기

내 SecurityContact 클래스에 대한 코드입니다. 이 시도 :

SELECT sc 
FROM SecurityContact sc 
LEFT JOIN FETCH sc.agentContact 
LEFT JOIN FETCH sc.auditContact 
WHERE sc.securityId=:securityId2 
+0

어떤 이유로 든, Hibernate는 쿼리로 annotated.xml을 빌드 할 때 에러를 발생시킵니다. –

+0

어떤 종류의 오류가 있습니까? 최대 절전 모드의 버전은 무엇입니까? –

+0

기본적으로 annotated.xml 파일을 빌드하지 못했습니다. 이 문제는 Hibernate가 쿼리에 대해 좋아하지 않는 무언가가있을 때 발생합니다. 나는 버전 3.4.0을 사용하고있다. –