2014-07-24 2 views
0

J'essaie de faire fonctionner une requête JPQL mais je n'arrive pas à la faire correctement.JPQL en utilisant MAX et JOIN

J'ai 2 classes d'entité, produit et paquet. Un produit peut avoir plusieurs paquets (peut-être aucun), dont chacun a une date d'expiration. J'essaie d'écrire une requête qui renvoie l'identifiant du produit, l'identifiant du pack et la date d'expiration, mais uniquement pour le pack qui a expiré le plus récemment, et seulement si cette date d'expiration est comprise entre deux valeurs.

Code simplifié ci-dessous:

@Entity 
public class Product { 
    @Id 
    long id; 

    @OneToMany(fetch=FetchType.EAGER, mappedBy="product", cascade={CascadeType.ALL}) 
    Set<Pack> packs; 
} 

public class Pack { 
    @Id 
    long id; 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="product_id", nullable=false) 
    Product product; 

    @Temporal(TemporalType.DATE) 
    Date expiryDate; 
} 

Mon JPQL est la suivante:

"select pk.product.id, pk.id, MAX (pk.expiryDate) comme maxExpiry de" + Pack.class.getName() + "gauche pk rejoindre le groupe pr pk.product par pp.id"

Je pense que cela fonctionne bien, mais en ajoutant dans la deuxième résolution triction échoue avec 'une utilisation incorrecte du groupe par' erreurs dans mysql si je fais ceci:

"sélectionner pk.product.id, pk.id, MAX (pk.expiryDate) comme maxExpiry de" + Pack. class.getName() + "gauche pk rejoindre pk.product pr où MAX (pk.expiryDate) entre: début et: groupe terminal par pp.id"

quelqu'un peut-il me aider à obtenir ces deux restrictions dans un requête unique? Merci.

Répondre

2

Que diriez-vous:

SELECT pk.product.id, pk.id, pk.expiryDate 
FROM Pack pk 
WHERE pk.expiryDate = (SELECT MAX(ppk.expiryDate) FROM Pack ppk where ppk.product = pk.product) AND 
     pk.expiryDate BETWEEN :start AND :end 

S'il vous plaît noter que s'il y avait plus d'un paquet avec date d'expiration maximale, cette requête retourne plus d'un produit et un ensemble de paquets.

+0

Salut, désolé a pris un certain temps pour répondre - c'est presque là mais je devais ajouter l'endroit où sélectionner interne pour le faire fonctionner. Merci! – fancyplants

+0

Pouvez-vous jeter un oeil à la question suivante s'il vous plaît? https://stackoverflow.com/q/44437322/363573 – Stephan