2015-10-05 102 views
0

閱讀所有文檔,在@ManyToOne上使用@Fetch(FetchMode.JOIN)默認情況下,我相信會生成一個左外部聯接,但對我而言,它始終生成一個內部聯接。這是我的豆子:@ManyToOne加入FetchMode生成內部聯接

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.persistence.Table; 

import org.hibernate.annotations.Fetch; 
import org.hibernate.annotations.FetchMode; 

/** 
* PensionMember entity. @author MyEclipse Persistence Tools 
*/ 
@Entity 
@Table(name = "Z_PENSION_MEMBERS", schema = "DANAOS") 
public class PensionMember implements java.io.Serializable { 

    private static final long serialVersionUID = -4541446336298304689L; 

    // Fields 

    private Long id; 
    private Long personsCode; 
    private String employeeCode; 
    private String personType; 
    private CrewOfficeEmployee employee; 
    private PersonTO person; 

    // Property accessors 
    @Id 
    @Column(name = "ID", unique = true, nullable = false, precision = 0) 
    public Long getId() { 
     return this.id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    @Column(name = "EMPLOYEE_CODE", length = 12) 
    public String getEmployeeCode() { 
     return this.employeeCode; 
    } 

    public void setEmployeeCode(String employeeCode) { 
     this.employeeCode = employeeCode; 
    } 

    @ManyToOne(cascade = CascadeType.REFRESH, optional=true) 
    @JoinColumn(name = "EMPLOYEE_CODE", insertable = false, updatable = false) 
    @Fetch(FetchMode.JOIN) 
    public CrewOfficeEmployee getEmployee(){ 
     return employee; 
    } 

    public void setEmployee(CrewOfficeEmployee employee){ 
     this.employee = employee; 
    } 

    @Column(name = "PERSONS_CODE", precision = 126, scale = 0, insertable = false, updatable = false) 
    public Long getPersonsCode() { 
     return this.personsCode; 
    } 

    public void setPersonsCode(Long personsCode) { 
     this.personsCode = personsCode; 
    } 

    @ManyToOne(cascade = CascadeType.REFRESH, optional=true) 
    @JoinColumn(name = "PERSONS_CODE") 
    @Fetch(FetchMode.JOIN) 
    public PersonTO getPerson() { 
     return person; 
    } 

    public void setPerson(PersonTO person) { 
     this.person = person; 
    } 

    @Column(name = "PERSON_TYPE", nullable = false, length = 1) 
    public String getPersonType() { 
     return this.personType; 
    } 

    public void setPersonType(String personType) { 
     this.personType = personType; 
    } 
} 

import java.util.Date; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.FetchType; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.persistence.Table; 

import org.hibernate.annotations.Fetch; 
import org.hibernate.annotations.FetchMode; 

/** 
* CrewOfficeEmployee entity. @author MyEclipse Persistence Tools 
*/ 
@Entity 
@Table(name = "Z_CREW_OFFICE_EMPLOYEES", schema = "DANAOS") 
public class CrewOfficeEmployee implements java.io.Serializable { 

    private static final long serialVersionUID = -5900130959401376537L; 

    // Fields 

    private String id; 
    private Integer crewOfficeJobTitleId; 
    private String name; 
    private String surname; 
    private Date dateOfBirth; 
    private Date effectiveJoiningDate; 
    private Date joiningDate; 
    private Date leavingDate; 

    // Property accessors 
    @Id 
    @Column(name = "ID", unique = true, nullable = false, length = 12) 
    public String getId() { 
     return this.id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    @Column(name = "JOB_TITLE_ID", nullable = false) 
    public Integer getCrewOfficeJobTitleId() { 
     return crewOfficeJobTitleId; 
    } 

    public void setCrewOfficeJobTitleId(Integer crewOfficeJobTitleId) { 
     this.crewOfficeJobTitleId = crewOfficeJobTitleId; 
    } 

    @Column(name = "NAME", nullable = false, length = 30) 
    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @Column(name = "SURNAME", nullable = false, length = 30) 
    public String getSurname() { 
     return this.surname; 
    } 

    public void setSurname(String surname) { 
     this.surname = surname; 
    } 

    @Column(name = "DATE_OF_BIRTH", nullable = false, length = 7) 
    public Date getDateOfBirth() { 
     return this.dateOfBirth; 
    } 

    public void setDateOfBirth(Date dateOfBirth) { 
     this.dateOfBirth = dateOfBirth; 
    } 

    @Column(name = "EFFECTIVE_JOINING_DATE", nullable = false, length = 7) 
    public Date getEffectiveJoiningDate() { 
     return this.effectiveJoiningDate; 
    } 

    public void setEffectiveJoiningDate(Date effectiveJoiningDate) { 
     this.effectiveJoiningDate = effectiveJoiningDate; 
    } 

    @Column(name = "JOINING_DATE", nullable = false, length = 7) 
    public Date getJoiningDate() { 
     return this.joiningDate; 
    } 

    public void setJoiningDate(Date joiningDate) { 
     this.joiningDate = joiningDate; 
    } 

    @Column(name = "LEAVING_DATE", length = 7) 
    public Date getLeavingDate() { 
     return this.leavingDate; 
    } 

    public void setLeavingDate(Date leavingDate) { 
     this.leavingDate = leavingDate; 
    } 
} 

這是我的查詢:

Criteria crit = getSession().createCriteria(PensionMember.class); 
crit.createAlias("employee", "employee"); 
crit.createAlias("person", "person"); 
crit.add(
    Restrictions.or(
     Restrictions.and(
      Restrictions.eq(PERSON_TYPE, "V"), 
      Restrictions.like("person.personsSurname", surname, MatchMode.START).ignoreCase() 
     ), 
     Restrictions.and(
      Restrictions.eq(PERSON_TYPE, "O"), 
      Restrictions.like("employee.surname", surname, MatchMode.START).ignoreCase() 
     ) 
    ) 
); 

...這是生成的SQL:

select * from (select this_.ID as ID23020_6_, this_.EMPLOYEE_CODE as EMPLOYEE3_23020_6_, this_.PERSONS_CODE as PERSONS7_23020_6_, 
this_.PERSON_TYPE as PERSON6_23020_6_, employee1_.ID as ID23010_0_, employee1_.JOB_TITLE_ID as JOB2_23010_0_, 
employee1_.DATE_OF_BIRTH as DATE3_23010_0_, employee1_.EFFECTIVE_JOINING_DATE as EFFECTIVE4_23010_0_, 
employee1_.JOINING_DATE as JOINING5_23010_0_, employee1_.LEAVING_DATE as LEAVING6_23010_0_, 
employee1_.NAME as NAME23010_0_, employee1_.SURNAME as SURNAME23010_0_, person2_.STATUS_CODE as STATUS2_22758_1_, etc 
from DANAOS.Z_PENSION_MEMBERS this_ 
inner join DANAOS.Z_CREW_OFFICE_EMPLOYEES employee1_ on this_.EMPLOYEE_CODE=employee1_.ID 
inner join PERSONS person2_ on this_.PERSONS_CODE=person2_.PERSONS_CODE 
where ((this_.PERSON_TYPE=? and lower(person2_.PERSONS_SURNAME) like ?) or 
(this_.PERSON_TYPE=? and lower(employee1_.SURNAME) like ?))) where rownum <= ? 

怎麼來的?有人能告訴我我做錯了什麼嗎?

感謝, 尼爾

我使用Hibernate的3.6.10順便說一句

+0

你能提供您Z_PENSION_MEMBERS表的DDL? –

回答

0
@ManyToOne(cascade = CascadeType.REFRESH, optional=true) 
@JoinColumn(name = "EMPLOYEE_CODE", insertable = false, updatable = false) 
@Fetch(FetchMode.JOIN)  
public CrewOfficeEmployee getEmployee(){ 
    return employee; 
} 

首先改變的 「插入=假」 爲true。

我得到(左外連接):

休眠:

選擇this_.ID爲ID1_1_1_,this_.EMPLOYEE_CODE1爲EMPLOYEE3_1_1_, this_.EMPLOYEE_CODE爲EMPLOYEE2_1_1_,crewoffice2_.ID爲ID1_0_0_ , crewoffice2_.JOB_TITLE_ID如JOB_TITL2_0_0_, crewoffice2_.DATE_OF_BIRTH如DATE_OF_3_0_0_, crewoffice2_.EFFECTIVE_JOINING_DATE如EFFECTIV4_0_0_, crewoffice2_.JOINING_DATE如JOINING_5_0_0_,crewoffice2_.LEAVING_DATE 爲LEAVING_6_0_0_,crewoffice2_.NAME爲NAME7_0_0_, crewoffice2_.SURNAME作爲SURNAME8_0_0_從Z_PENSION_MEMBERS THIS_ 左外連接由this_.ID ASC Z_CREW_OFFICE_EMPLOYEES上 this_.EMPLOYEE_CODE1 = crewoffice2_.ID爲了crewoffice2_

我覺得你的代碼應該管用。

+0

感謝您的回覆。這讓我意識到,這是問題而不是映射的問題。 findById()提供了一個外連接,但是我正在運行的查詢(請參閱編輯的問題)仍然會創建一個內連接 –

0

已經意識到這是標準的查詢,這是問題,解決的辦法是改變createAlias()方法:

Criteria crit = getSession().createCriteria(PensionMember.class); 
crit.createAlias("employee", "employee", CriteriaSpecification.LEFT_JOIN); 
crit.createAlias("person", "person", CriteriaSpecification.LEFT_JOIN);