web-dev-qa-db-fra.com

Hiberner Joindre en utilisant des critères et des restrictions

J'ai 2 entités comme

paie câble-fille.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;

}

PayoutDétails .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**;
}

Je veux écrire une requête en utilisant des critères Hibernate comme

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') ";

J'ai écrit une requête comme ça

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();
    }

Mais donne une erreur comme

org.hibernate.QuiseryException: ne pouvait pas résoudre la propriété: ChequeSuSueDeDate de: org.commission.domain.payout.payoutDétails

Je pense que c'est essayer de trouver chequeIssuedDate champ dans PayoutDetails, mais ce champ est en PayoutHeader. Comment spécifier des alias lors de la jointure?

13
Rahul Agrawal

Le criteria.setFetchMode("PayoutHeader", FetchMode.JOIN) Spécifie simplement que vous souhaitez obtenir l'en-tête par une jointure et dans ce cas est probablement inutile. Cela ne change pas quelle table est utilisée dans les restrictions. Pour cela, vous voulez probablement créer des critères supplémentaires ou un alias, plus ou moins comme suit:

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();
    }

ou (en utilisant un alias)

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();
    }

Voir les documents hibernés sur les requêtes de critères pour des exemples de ceci.

Il n'est probablement pas approprié de convertir le advisorId à une chaîne, car c'est en fait un Long et probablement mappé sur un champ de numéro dans SQL.

Il est courant de ne pas aussi pas mapper quelque chose comme ceci advisorId champ du tout si vous mappez le champ advisor et utilisez une restriction basée sur le champ advisor, de la même manière à la manière dont ces offres avec le champ payoutHeader.

Je ne m'inquiéterais pas d'obtenir tous les champs de l'en-tête, mais cela peut se comporter un peu différemment si vous obtenez la version createCriteria au travail.

14
Don Roby