2015-10-05 2 views
0

Чтение всей документации с использованием @Fetch (FetchMode.JOIN) в @ManyToOne должно по умолчанию, я считаю, что генерировать левое внешнее соединение, но для меня он всегда генерирует внутреннее соединение. Это мои бобы:@ManyToOne с JOIN 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

Можете ли вы предоставить в DDL вашей таблицы Z_PENSION_MEMBERS? –

ответ

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

первую очередь изменения "вставной = ложь" истина.

Я получаю (левое внешнее соединение):

Hibernate:

выберите 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_ левое внешнее соединение Z_CREW_OFFICE_EMPLOYEES crewoffice2_ на порядка this_.EMPLOYEE_CODE1 = crewoffice2_.ID по this_.ID возрастанию

Я думаю, что ваш код должно сработать.

+0

Спасибо за ваш ответ. Это заставило меня понять, что проблема была не в задаче, а в сопоставлении. Функция findById() предоставляет внешнее соединение, но запрос, который я выполнял (см. Отредактированный вопрос), по-прежнему создает внутреннее соединение –

0

Осознав это критерии запроса, была проблема, решение было изменить createAlias ​​() методы:

Criteria crit = getSession().createCriteria(PensionMember.class); 
crit.createAlias("employee", "employee", CriteriaSpecification.LEFT_JOIN); 
crit.createAlias("person", "person", CriteriaSpecification.LEFT_JOIN); 
Смежные вопросы