2013-03-05 4 views
0

Je les classes suivantes (simplifiée pour plus de clarté):EJBQL - Comment trier les résultats de la requête par un champ LEFT JOIN

Class Top { 
    InternationalStringType name; 
} 

Class InternationalStringType { 
    List<LocalizedStringType> localizedString; 
} 

Class LocalizedStringType { 
    String value; 
} 

La requête EJBQL suivante permet d'extraire avec succès toutes les instances de Top avec leurs sous-objets peuplé :

SELECT DISTINCT Object(t) FROM Top t LEFT OUTER JOIN t.name nm LEFT OUTER JOIN nm.localizedString nm_ls 

Je voudrais modifier la requête ci-dessus de telle sorte que les résultats sont triés par Top.name.localizedString.value

Quelle est la syntaxe correcte pour ce faire? J'ai essayé la requête suivante mais je reçois « ERREUR: SELECT pour DISTINCT, les expressions ORDER BY doit apparaître dans la liste de sélection »

SELECT DISTINCT Object(t) FROM Top t LEFT OUTER JOIN t.name nm LEFT OUTER JOIN nm.localizedString nm_ls ORDER BY nm_ls.value ASC 

Ce ne est pas clair pour moi quoi mettre dans la liste de sélection pour la clause ORDER BY.

Après donner des erreurs pour le « » après l'objet (t), peu importe ce que je mets après la virgule:

SELECT DISTINCT Object(t), Object(nm_ls) FROM Top t LEFT OUTER JOIN t.name nm LEFT OUTER JOIN nm.localizedString nm_ls ORDER BY nm_ls.value ASC 

Dans le cas où la mise en œuvre pertinente mon JPA est mise en veille prolongée 3.6.4.Final. TIA pour votre aide.

Répondre

0

J'ai été en mesure de faire fonctionner la clause ORDER BY avec ma requête en supprimant simplement le qualificateur DISTINCT dans la clause SELECT. Je ne suis pas sûr de comprendre les points, mais la requête modifiée suivante a parfaitement fonctionné!

SELECT t FROM Top t LEFT JOIN t.name nm LEFT JOIN nm.localizedString nm_ls ORDER BY nm_ls.value ASC 

-je obtenir un résultat maintenant réglé avec les instances Top triées par l'attribut Top.name.localizedString.value comme je l'espérais.

Si quelqu'un peut expliquer pourquoi DISTINCT ne fonctionne pas ce serait génial. Merci.

+0

Vous forcez une jointure à locizedString qui est une collection. Cela signifie que pour une seule entité, il y aura X nombre de lignes uniques (une pour chaque localiséeString référencée), qui sont toutes nécessaires pour construire complètement cette entité. Puisque tous les X sont distincts, distincts n'ont pas l'effet que vous voulez - qui est d'obtenir un résultat unique pour votre entité supérieure. JPA exige que chaque ligne lue soit renvoyée sous la forme d'une entité, mais certains fournisseurs JPA peuvent autoriser le filtrage via une API native. – Chris

0

Les champs utilisés dans la clause ORDER BY doivent être des champs CMP, ils ne peuvent pas être des identificateurs d'entité ou des champs CMR. En outre, vous devez faire attention aux champs CMP que vous spécifiez dans la clause ORDER BY. Si la requête sélectionne une collection d'entités, la clause ORDER BY ne peut être utilisée qu'avec les champs CMP du type d'entité sélectionné. Par exemple, la requête suivante est illégale, car le champ CMP utilisé dans la clause ORDER BY n'est pas un champ du type d'entité sélectionné.

OBJET SELECT (c) FROM Customer AS c ORDER BY c.address.city

Parce que la ville champ CMP est pas un champ direct CMP de l'EJB client, vous ne pouvez pas l'utiliser dans la clause ORDER BY clause. Les seuls champs CMP que vous pouvez utiliser dans la clause ORDER BY sont ceux qui sont des champs CMP directs du type d'entité sélectionné. C'est une restriction déraisonnable.

Une restriction similaire s'applique aux résultats CMP. Le champ CMP utilisé dans la clause ORDER BY doit être le même que le champ CMP identifié dans la clause SELECT. Par exemple, la requête suivante est illégale, car le CMP identifié dans la clause SELECT diffère de celui utilisé dans la clause ORDER BY.

SELECT c.address.city FROM Customer AS c ORDER BY c.address.state

Dans la requête ci-dessus, nous voulions une liste de toutes les villes, commandées par l'État. Malheureusement, c'est illégal. Vous ne pouvez pas commander par le champ CMP d'état si vous sélectionnez en utilisant le champ CMP de la ville. J'ai entendu dire que cette deuxième restriction peut nous avoir été imposée par les limitations de l'un des principaux systèmes RDBS, qui ne peuvent pas être ordonnés par des colonnes non présentes dans la clause select - rappelez-vous que EJB QL est compilé dans un langage de requête natif, qui dans SQL Server est RDBS. Les limites des principaux fournisseurs seront un facteur dans la création de toute abstraction - le plus petit dénominateur commun prévaudra.

+0

J'ai obtenu la réponse de l'article suivant http://www.theserverside.com/news/1321184/EJB-21-adds-new-functionality-to-EJB-QL-Monson-Haefels-Guide-to- Enterprise-JavaBeans où je vous donne une explication sur votre problème et j'espère que cet article met la lumière dessus. – oggie0563

+0

Je n'utilise aucun EJB. J'utilise seulement les POJO qui sont persistés en utilisant JPA (hibernate entitymanager). Que signifient CMP et CMR dans ce contexte? –