2012-07-16 63 views
14

我有2个实体休眠加入使用标准和限制

PayoutHeader.java

@Entity 
public class PayoutHeader extends GenericDomain implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id;   
    @Column 
    private Integer month; 
    @Column 
    private Integer year; 
    @OneToOne 
    private Bank bank; 
    @Column 
    private Double tdsPercentage; 
    @Temporal(javax.persistence.TemporalType.DATE) 
    private Date **chequeIssuedDate**; 

    @Temporal(javax.persistence.TemporalType.DATE) 
    private Date entryDate; 

} 

PayoutDetails的.java

@Entity 
public class PayoutDetails { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id;   

    @ManyToOne 
    private PayoutHeader payoutHeader; 

    @Column 
    private Double amount; 
    @Column 
    private String bankName; 
    @Temporal(javax.persistence.TemporalType.DATE) 
    private Date clearingDate; 
    @OneToOne  
    private Advisor advisor; 

    @Column 
    private Long **advisorId**; 
} 

我想用Hibernate的标准编写查询像

Select pd.* from PayoutDetails pd, PayoutHeader ph where pd.payoutheaderId = ph.id and pd.advisorId = 1 and and ph.chequeIssuedDate BETWEEN STR_TO_DATE('01-01-2011', '%d-%m-%Y') AND STR_TO_DATE('31-12-2011', '%d-%m-%Y') "; 

我写这样的查询

public List<PayoutDetails> getPayoutDetails(AdvisorReportForm advisorReportForm) { 
     Criteria criteria = getSession().createCriteria(PayoutDetails.class); 

     if (advisorReportForm.getAdvisorId() != null && advisorReportForm.getAdvisorId() > 0) { 
      criteria.add(Restrictions.eq("advisorId", advisorReportForm.getAdvisorId().toString())); 
     } 

     criteria.setFetchMode("PayoutHeader", FetchMode.JOIN) 
       .add(Restrictions.between("chequeIssuedDate", advisorReportForm.getFromDate(), advisorReportForm.getToDate()));   

     return criteria.list(); 
    } 

不过是给误差

org.hibernate.QueryException:无法解析属性:org.commission.domain:的 chequeIssuedDate。 payout.PayoutDetails

我认为是试图找到chequeIssuedDate字段在PayoutDetails,但是这个字段在PayoutHeader。如何在连接过程中指定别名?

回答

15

criteria.setFetchMode("PayoutHeader", FetchMode.JOIN)只是指定您想通过连接获取标头,在这种情况下可能不需要。它不会更改在限制中使用哪个表。对于这一点,你可能想创建一个额外的标准或别名,或多或少如下:

public List<PayoutDetails> getPayoutDetails(AdvisorReportForm advisorReportForm) { 
     Criteria criteria = getSession().createCriteria(PayoutDetails.class); 

     if (advisorReportForm.getAdvisorId() != null && advisorReportForm.getAdvisorId() > 0) { 
      criteria.add(Restrictions.eq("advisorId", advisorReportForm.getAdvisorId().toString())); 
     } 

     criteria.createCriteria("payoutHeader") 
       .add(Restrictions.between("chequeIssuedDate", advisorReportForm.getFromDate(), advisorReportForm.getToDate()));   

     return criteria.list(); 
    } 

或(使用别名)

public List<PayoutDetails> getPayoutDetails(AdvisorReportForm advisorReportForm) { 
     Criteria criteria = getSession().createCriteria(PayoutDetails.class); 

     if (advisorReportForm.getAdvisorId() != null && advisorReportForm.getAdvisorId() > 0) { 
      criteria.add(Restrictions.eq("advisorId", advisorReportForm.getAdvisorId().toString())); 
     } 

     criteria.createAlias("payoutHeader", "header") 
       .add(Restrictions.between("header.chequeIssuedDate", advisorReportForm.getFromDate(), advisorReportForm.getToDate()));   

     return criteria.list(); 
    } 

对于这方面的例子见the Hibernate docs on Criteria Queries

也可能不适合将advisorId转换为字符串,因为它实际上是Long,并且可能映射到sql中的数字字段。

这是常见的,如果你基础上advisor这个领域涉及的是payoutHeader字段映射advisor,并使用限制,同样的方式也不会映射像这样advisorId场都没有。

我不担心从标题中获取所有字段,但如果您的createCriteria版本能够正常工作,它可能会有点不同。

+0

我试过第一个给出的解决方案,它给出的错误为“org.hibernate.QueryException:无法解析属性:payoutHeader:org.commission.domain.payout.PayoutDetails” – 2012-07-16 11:23:31

+0

感谢Don Roby :)第二种方法的工作原理。 – 2012-07-16 11:31:09

+0

当我在选择原因打印生成的SQL时,它具有来自两个表的所有列,我只需要来自PayoutDetails表的列。如何为此设置投影? – 2012-07-16 11:32:10