Connaissez-vous un moyen d'obtenir un ensemble de résultats distinct sans utiliser ResultTransformer lors de l'utilisation de SetFirstResult et SetMaxResults ?
-
23-08-2019 - |
Question
Lorsque j'utilise SetFirstResult et SetMaxResult et si la requête a rejoint, le résultat a des résultats en double au lieu d'être uniques.
Ensuite, j'utilise tous les types d'assistants distincts pour l'API de critères.Mais il ne filtre pas l'ensemble des résultats, il filtre simplement le résultat paginé.
Comment puis-je surmonter ce problème ?
Merci
La solution
Je l'ai trouvé un chose hacky à surmonter cette question.
La seule « solution » pour ce qui Je suis en mesure de trouver est de émettre deux requêtes des critères objet mêmes critères. Le premier obtient l'identifiant est le second est contrained aux ids.
// mis en place crtieria que vous le souhaitez, y compris la pagination myCriteria = doStuffToSetupCriteria (); myCriteria.setFirstResult ((page-1) * itemsPerPage); myCriteria.setMaxResults (itemsPerPage);
// obtenir la liste si les clés primaires myCriteria.setProjection (Projections.distinct (Projections.property ( "myAllias.id")); Liste ids = gacc.list ();
// maintenant ajouter les ID dans la restriction myCriteria.add (Restrictions.in ( "myAlias.id, ids));
// nettoyer de la dernière course de critiera gacc.setProjection (null); gacc.setFirstResult (0); gacc.setMaxResults (Integer.MAX_VALUE);
// votre liste de résultats = objets gacc.list ()
Un peu hacky Je suis d'accord, mais la seule soltion acceptable que je pouvais trouver donnée ce limitiation.
Autres conseils
J'ai construit une solution similaire mais en un seul voyage vers DB :
DetachedCriteria subQuery = ...//-->Ajoutez tous les critères souhaités, y compris "SetFirstResult" et "SetMaxResults".
DetachedCriteria rootQuery = DetachedCriteria.For();// où T est une entité
sous-requête.SetProjection( Projections.Distinct( Projections.ProjectionList(). Ajouter(Projections.Alias(Projections.Property(« ID »), « ID »)) ) );
// Note:toutes mes entités héritent d’une classe de base qui contient une propriété « ID » rootQuery.Add(Subqueries.PropertyIn(« ID », subQuery)) ;
// ...puis utilisez rootQuery pour obtenir la liste de T et aucun élément répété ne sera récupéré.
J'espère que quelqu'un trouvera cette implémentation utile :)
Romain