2010-12-14 68 views
1

J'ai une requête assez complexe qui fonctionne en SQL, mais je voudrais l'exprimer en HQL pour la portabilité. Je vais chercher une valeur de préférence configurée par l'utilisateur si elle existe, sinon je dois utiliser une valeur par défaut. Cette valeur doit être soustrait de la date et la correspondance avec une colonne dans la table que je suis intéressé par:Comment construire une requête Hibernate avancée avec OU et résumer des fonctions

select d.id, d.guid, d.deletetimestamp, u.id 
from descriptor d, ownerkey ow, user u 
where 
    d.parentid in 
     (select td.id 
     from descriptor td, store s 
     where s.type = 'Trash' 
     and s.descriptorid = td.id 
     ) 
    and d.ownerkeyid = ow.id 
    and ow.ownerid = u.id 
    and 
     (
     (d.deletetimestamp < CURRENT_TIMESTAMP() - INTERVAL 
      (select pv.value 
      from preferencevalue pv, userpreference up 
      where u.id = up.userid 
      and up.preferenceid = 26 
      and up.value = pv.id) 
      DAY) 
     or 
     (d.deletetimestamp < CURRENT_TIMESTAMP() - INTERVAL 
      (select cast(pv.value as SIGNED) 
      from preferencevalue pv, defaultpreference dp 
      where dp.preferenceid = 26 
      and not exists(select up.userid from userpreference up where u.id = up.userid and up.preferenceid = 26) 
      and dp.value = pv.id) 
      DAY) 
     ) 

Je suis en train de construire ce en utilisant l'API de critères qui semble inclure la plupart des les opérateurs logiques dont j'ai besoin (égal, supérieur à, ou, isEmpty/isNull), mais je ne sais pas comment j'exprimerais toutes ces parties.

L'utilisation d'une vue n'est pas une option pour l'instant puisque nous utilisons MySQL comme base de données de production alors que les tests d'intégration sont exécutés avec la base de données H2 inmemory. Je ne suis pas en mesure de trouver la fonction de soustraction sata dans H2 alors que MySQL supporte cela.

Les champs de sélection ne sont pas importants car ils ont seulement été utilisés à des fins de test.

Répondre

0
  1. Vous pouvez utiliser Restrictions.disjunction() pour et -et Restrictions.conjuction() pour et clauses.
  2. Pour faire référence à une propriété d'une entité (comme pv.value), vous pouvez utiliser Projections.property("value")
  3. pour la coulée Je ne sais pas, peut-être en utilisant l'annotation @Formula sur votre entité? Mais ceci est un hibernation et non une annotation JPA.
  4. autant que je sache, il n'y a pas d'équivalent pour INTERVAL en veille prolongée, mais dans ce cas (peut-être aussi pour le casting ci-dessus), vous pouvez utiliser Restrictions.sqlRestriction("some sql...")

Ce sera un défi de mettre tout cela ensemble pour transformer votre requête pour mettre en veille les critères.

greetz,
Stijn