【问题标题】:Hibernate Join using criteria and restrictionsHibernate Join 使用条件和限制
【发布时间】:2012-07-15 05:01:29
【问题描述】:

我有 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 Criteria 的方式编写查询

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:无法解析属性: chequeIssuedDate of: org.commission.domain.payout.PayoutDetails

我认为正在尝试在PayoutDetails 中找到chequeIssuedDate 字段,但该字段在PayoutHeader 中。加入时如何指定别名?

【问题讨论】:

    标签: java hibernate hibernate-criteria


    【解决方案1】:

    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 并使用基于 advisor 字段的限制,则通常也不映射类似 advisorId 字段的内容,类似于处理 payoutHeader 字段的方式.

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

    【讨论】:

    • 我已经尝试过你给出的第一个解决方案,它给出的错误是“org.hibernate.QueryException: could not resolve property: payoutHeader of: org.commission.domain.payout.PayoutDetails”
    • 当我在 select 中打印生成的 SQL 时,因为它包含两个表中的所有列,我只需要 PayoutDetails 表中的列。如何为此设置投影?
    • 检查大小写是否匹配并尝试变体 - hibernate 绝对区分大小写。也可能值得尝试查询的别名版本,但它可能有同样的问题。此外,我将在顾问的内容上添加一些其他注释,这不应该导致这个问题,但可能会导致其他问题。
    • 假设实体名称为“a.b.c.AbcXyz”,表名称为“ABC_XYZ”。我应该在 criteria.createAlias 中使用什么值?
    猜你喜欢
    • 2016-09-29
    • 1970-01-01
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 2011-01-13
    • 2011-12-08
    • 2018-01-19
    相关资源
    最近更新 更多