2010-05-16 5 views
1

J'ai été confronté à un problème lors de l'interrogation avec les critères Hibernate dans Grails.Taille de l'assosiation dans les critères Hibernate

Jetez un oeil:

def visitors = Client.withCriteria{ 
      visits{ 
      use (TimeCategory) {between('date',date,date+1.month-1)} 
      } 
      sizeGe("visits",params.from) 
      sizeLe("visits",params.to) 
      fetchMode("visits", FM.JOIN) 
}; 

-je besoin que les clients, ce qui a nombre de visites au cours du mois entre de et à limites.

Mais maintenant taille * restrictions est appliqué à toutes les visites. Donc, si le client a une visite dans ce mois, et la visite au mois précédent. Et si je mets de = 2, ce client sera en résultat. Mais ça ne devrait pas être là.

// UPD: la chose comme que sizeGe et sizeLe restrictions fonctionnent pas comme je l'attends. De mon point de vue, ils devraient être appliqués après entre restriction, mais ils ne le sont pas.

Par exemple:

def client = new Client(); 

client.visits.add(new Visit(date:'2010-03-16')); 
client.visits.add(new Visit(date:'2010-05-16')); 
client.visits.add(new Visit(date:'2010-05-17')); 
client.save(); 

Et puis je veux si:

  • date = Date.parse ('aaaa-MM', '2010-05')
  • params.from = 2

critères doivent retourner ce client, et si

  • params.from = 3

pas de retour;
Mais il revient, car sizeGe est en cours d'application à toutes les visites, quelle que soit la date.

// END UPD. Faites-moi savoir si smth n'est toujours pas clair.

Toute aide est appréciée.

Merci, Vova.

+0

Pourriez-vous élaborer plus? –

Répondre

1

Vous auriez besoin d'une clause having pour faire cela et j'ai trouvé sur issue open in Hibernate's Jira pour ajouter le support pour cela.

En attendant, vous devez utiliser HQL et écrire la requête à la main, see this. Si vous n'avez pas besoin de modifier les restrictions de la requête en fonction de certains champs sélectionnés, vous devriez toujours aller avec HQL, il peut être mis en cache.

0

Merci Felipe.

De plus, j'ai choisi d'utiliser sqlRestriction.Bien sûr, il a quelques problèmes de portabilité mais cela fonctionne:

def visitors = c.listDistinct{ 
     use(TimeCategory){ 
       visits{ 

        between('date',date,date+1.month-1) 
       } 

       sqlRestriction(
         """(
          select count(*) 
            from visit v 
          where 
           v.visitor_id={alias}.id 
           and v.date between 
             '${date.format("yyyy-MM-dd")}' 
             and '${(date+1.month-1).format("yyyy-MM-dd")}' 
          ) 
          between ${params.from} and ${params.to}""" 
       ) 
      } 
    } 

Merci, Vova.

Questions connexes