@ManyToOne与JOIN FetchMode生成内部联接

时间:2015-10-05 09:16:55

标签: java hibernate join

在@ManyToOne上使用@Fetch(FetchMode.JOIN)读取所有文档应该默认情况下我相信会生成一个左外连接,但对我来说它始终生成一个内连接。这些是我的豆子:

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 btw

2 个答案:

答案 0 :(得分:1)

意识到这是问题的标准查询,解决方案是更改createAlias()方法:

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

答案 1 :(得分:0)

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

首先改变&#34; insertable = false&#34;为真。

我得到了(左外连接):

休眠:

  

选择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 as SURNAME8_0_0_来自Z_PENSION_MEMBERS this_   左外连接Z_CREW_OFFICE_EMPLOYEES crewoffice2_ on   this_.EMPLOYEE_CODE1 = crewoffice2_.ID由this_.ID asc命令

我认为您的代码应该有效。