14.9. La clause where

La clause where vous permet de réduire la liste des instances retournées. Si aucun alias n'existe, vous pouvez vous référer aux propriétés par leur nom :

from Cat where name='Fritz'

S'il y a un alias, utilisez un nom de propriété qualifié :

from Cat as cat where cat.name='Fritz'

retourne les instances de Cat dont name est égale à 'Fritz'.

select foo
from Foo foo, Bar bar
where foo.startDate = bar.date

retournera les instances de Foo pour lesquelles il existe une instance de bar avec la propriété date est égale à la propriété startDate de Foo. Les expressions utilisant la navigation rendent la clause where extrêmement puissante. Soit :

from Cat cat where cat.mate.name is not null

Cette requête se traduit en SQL par une jointure interne à une table. Si vous souhaitez écrire quelque chose comme :

from Foo foo
where foo.bar.baz.customer.address.city is not null

vous finiriez avec une requête qui nécessiterait quatre jointures en SQL.

L'opérateur = peut être utilisé pour comparer aussi bien des propriétés que des instances :

from Cat cat, Cat rival where cat.mate = rival.mate
select cat, mate
from Cat cat, Cat mate
where cat.mate = mate

La propriété spéciale (en minuscule) id peut être utilisée pour faire référence à l'identifiant d'un objet (vous pouvez aussi utiliser le nom de cette propriété).

from Cat as cat where cat.id = 123

from Cat as cat where cat.mate.id = 69

La seconde requête est particulièrement efficace. Aucune jointure n'est nécessaire !

Les propriétés d'un identifiant composé peuvent aussi être utilisées. Supposez que Person ait un identifiant composé de country et medicareNumber.

from bank.Person person
where person.id.country = 'AU'
    and person.id.medicareNumber = 123456
from bank.Account account
where account.owner.id.country = 'AU'
    and account.owner.id.medicareNumber = 123456

Une fois de plus, la seconde requête ne nécessite pas de jointure.

De même, la propriété spéciale class interroge la valeur discriminante d'une instance dans le cas d'une persistance polymorphique. Le nom d'une classe Java incorporée dans la clause where sera traduite par sa valeur discriminante.

from Cat cat where cat.class = DomesticCat

Vous pouvez aussi spécifier les propriétés des composants ou types utilisateurs composés (components, composite user types etc). N'essayez jamais d'utiliser un expression de navigation qui se terminerait par une propriété de type composant (qui est différent d'une propriété d'un composant). Par exemple, si store.owner est une entité avec un composant address

Un type "any" possède les propriétés spéciales id et class, qui nous permettent d'exprimer une jointure de la manière suivante (où AuditLog.item est une propriété mappée avec <any>).

from AuditLog log, Payment payment
where log.item.class = 'Payment' and log.item.id = payment.id

Dans la requête précédente, notez que log.item.class et payment.class feraient référence à des valeurs de colonnes de la base de données complètement différentes.