2012-04-10 51 views
0

我正在一个应用程序,我必须加入3-4表选择操作。 我是hibernate 3的注释并在下面添加了我的类结构。但是我尝试过在联接获取策略中使用很多变体,但是无法获得的结果2选择。请通过并尝试帮助我。 考生类Hibernate加入问题,同时加入两个以上的表

@JsonAutoDetect 
@Entity 
@Table(name="HC_RESUME_BANK") 
public class Candidates{ 

private int id; 
private String firstName; 
private String lastName; 
private String email; 
private String phone; 
@JsonUnwrapped 
private Set<CandidateStatus> candidateStats = new HashSet<CandidateStatus>(0); 

@OneToMany //(mappedBy="candidate") 
@Fetch(FetchMode.JOIN) 
@JoinColumn(name="ResID",nullable=false,referencedColumnName="RID") 
@JsonIgnore 
public Set<CandidateStatus> getCandidateStats() { 
     return candidateStats; 
} 
public void setCandidateStats(Set<CandidateStatus> candidateStats) { 
    this.candidateStats = candidateStats; 
} 

CandidateStatus类

@JsonAutoDetect 
@Entity 

@Table(name="HC_REQ_RESUME") 

public class CandidateStatus{ 

private int id; 
private String statusTitle; 
@JsonUnwrapped 
private Candidates candidate; 
private int reqid; 
private int resid; 

@JsonUnwrapped 
private Requirements requirement; 

@ManyToOne 
@Fetch(FetchMode.JOIN) 

@JoinColumn(name="ReqID",insertable=false,updatable=false) 
//@JsonIgnore 
public Requirements getRequirement() { 
    return requirement; 
} 
    @ManyToOne //(fetch = FetchType.LAZY,cascade=CascadeType.ALL,targetEntity=Candidates.class) 
@Fetch(FetchMode.JOIN) 
@JoinColumn(name="ResID",insertable=false,updatable=false) 
//@ForeignKey(name = "FK_ResID") 

public Candidates getCandidate() { 
    return candidate; 
} 

public void setCandidate(Candidates candidate) { 
    this.candidate = candidate; 
} 

客户端类

@JsonAutoDetect 
@Entity 
@Table(name="HC_CLIENTS") 
public class Clients{ 

private int id; 
private String clientName; 
@JsonUnwrapped 
private Set<Requirements> require= new HashSet<Requirements>(0); 
//private List<Requirements> require; 


@OneToMany //(fetch=FetchType.EAGER) 
@Fetch(FetchMode.JOIN) 
@JoinColumn(name="ClientID",referencedColumnName="RID") 


@JsonIgnore 
public Set<Requirements> getRequire() { 
    return require; 
} 
public void setRequire(Set<Requirements> require) { 
    this.require = require; 
} 

最后要求类

@JsonAutoDetect 
@Entity 

@Table(name="HC_REQUISITIONS") 
public class Requirements{ 

private int id; 
private int clientId; 
private String reqTitle; 
@JsonUnwrapped 
private Clients client; 

@ManyToOne 
@Fetch(FetchMode.JOIN) 
@JoinColumn(name="ClientID",insertable=false,updatable=false) 
//@JsonIgnore 
public Clients getClient() { 
    return client; 
} 
public void setClient(Clients client) { 
    this.client = client; 
} 
    @OneToMany 
@Fetch(FetchMode.JOIN) 
@JoinColumn(name="ReqID",referencedColumnName="RID") 
@JsonIgnore 
public Set<CandidateStatus> getCandidateStatus() { 
    return candidateStatus; 
} 
public void setCandidateStatus(Set<CandidateStatus> candidateStatus) { 
    this.candidateStatus = candidateStatus; 
} 

我已经消除了的getter/setter方法用于避免unnessary代码。
由于N + 1发生的上述类关联中出现了什么问题? 查询:

return hibernateTemplate.find("from Requirements as req order by req.reqTitle"); 

我想只获取需求类的对象,但我得到的所有对象和查询

感谢您的时间的N + 1分的结果
萨钦

@RaulGogo:尝试了标准查询,但问题仍然存在。这些是查询的日志实例。并且我添加了@BatchSize(size = 100)通过执行批量提取减少了查询的数量。我在注释配置方面漏掉了什么?

Hibernate: 
    /* criteria query */ select 
    this_.RID as RID3_3_, 
    this_.ClientID as ClientID3_3_, 
    this_.ReqTitle as ReqTitle3_3_, 
    candidates2_.ReqID as ReqID3_5_, 
    candidates2_.RID as RID5_, 
    candidates2_.RID as RID1_0_, 
    candidates2_.ResID as ResID1_0_, 
    candidates2_.reqid as reqid1_0_, 
    candidates2_.ReqID as ReqID1_0_, 
    candidates2_.resid as resid1_0_, 
    candidates2_.StatusTitle as StatusTi4_1_0_, 
    candidates3_.RID as RID0_1_, 
    candidates3_.EmailID as EmailID0_1_, 
    candidates3_.FirstName as FirstName0_1_, 
    candidates3_.LastName as LastName0_1_, 
    candidates3_.Mobile as Mobile0_1_, 
    clients4_.RID as RID2_2_, 
    clients4_.ClientName as ClientName2_2_ 
from 
    HC_REQUISITIONS this_ 
left outer join 
    HC_REQ_RESUME candidates2_ 
     on this_.RID=candidates2_.ReqID 
left outer join 
    HC_RESUME_BANK candidates3_ 
     on candidates2_.ResID=candidates3_.RID 
left outer join 
    HC_CLIENTS clients4_ 
     on this_.ClientID=clients4_.RID 
order by 
    this_.ReqTitle asc 

    Hibernate: 
    /* load one-to-many com.options.model.Candidates.candidateStats */ select 
    candidates0_.ResID as ResID0_3_, 
    candidates0_.RID as RID3_, 
    candidates0_.RID as RID1_2_, 
    candidates0_.ResID as ResID1_2_, 
    candidates0_.reqid as reqid1_2_, 
    candidates0_.ReqID as ReqID1_2_, 
    candidates0_.resid as resid1_2_, 
    candidates0_.StatusTitle as StatusTi4_1_2_, 
    requiremen1_.RID as RID3_0_, 
    requiremen1_.ClientID as ClientID3_0_, 
    requiremen1_.ReqTitle as ReqTitle3_0_, 
    clients2_.RID as RID2_1_, 
    clients2_.ClientName as ClientName2_1_ 
from 
    HC_REQ_RESUME candidates0_ 
left outer join 
    HC_REQUISITIONS requiremen1_ 
     on candidates0_.ReqID=requiremen1_.RID 
left outer join 
    HC_CLIENTS clients2_ 
     on requiremen1_.ClientID=clients2_.RID 
where 
    candidates0_.ResID=? 

回答

0

尝试使用标准。

return getHibernateTemplate().execute(new HibernateCallback<List<Requirement>>() { 
     @Override 
     public List<Requirement>doInHibernate(Session session) throws HibernateException, SQLException { 
      return (List<Requirement>) session.createCriteria(Requirement.class) 
        .addOrder(Order.asc("reqTitle")) 
        .list(); 
     } 
    }); 

这确实一个通过reqTitle ASC SELECT * FROM需求订单,它将返回要求的列表。

+0

由于@RaulGogo'选择 this_.ClientID如ClientID3_3_, this_.ReqTitle如ReqTitle3_3_, 从 HC_REQUISITIONS THIS_ 左外上this_.RID = candidates2_.ReqID加入 HC_REQ_RESUME candidates2_ 左外连接 HC_RESUME_BANK candidates3_ 上candidates2_.ResID = candidates3_.RID 左外连接 HC_CLIENTS通过 this_.ReqTitle ASC上this_.ClientID = clients4_.RID 顺序clients4_ 0'这是日志查询的一部分打印。它仍然打印** N + 1查询**与连接。字符限制,所以不能发布整个日志。 – KillABug 2012-04-11 08:09:58

+0

更新了您的答案的问题。请通过。谢谢 – KillABug 2012-04-11 08:26:19

+0

增加了**。setFetchMode(FetchMode.LAZY)**,但没有改变结果。另外,BatchFetch有帮助,但是它是Fetch Strategies **中最好的解决方案吗? – KillABug 2012-04-12 06:11:38