Question

Existe-t-il un moyen de créer une requête Distinct dans HQL. Soit en utilisant le code "distinct". mot-clé ou une autre méthode. Je ne sais pas si distinct est un travail de clé valide pour HQL, mais je recherche l’équivalent HQL du mot clé SQL "distinct".

Était-ce utile?

La solution

Voici un extrait de code HTML que nous utilisons. (Les noms ont été modifiés pour protéger les identités)

String queryString = "select distinct f from Foo f inner join foo.bars as b" +
                " where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
        return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});

Autres conseils

Il convient de noter que le mot clé distinct dans HQL ne correspond pas directement au mot clé distinct dans SQL.

Si vous utilisez le mot clé distinct dans HQL, Hibernate utilisera parfois le mot clé SQL distinct , mais dans certaines situations, il utilisera un transformateur de résultat pour produire des résultats distincts. . Par exemple, lorsque vous utilisez une jointure externe comme celle-ci:

select distinct o from Order o left join fetch o.lineItems

Dans ce cas, il n'est pas possible de filtrer les doublons au niveau SQL. Hibernate utilise donc un ResultTransformer pour filtrer les doublons après l'exécution de la requête SQL.

faire quelque chose comme ça la prochaine fois

 Criteria crit = (Criteria) session.
                  createCriteria(SomeClass.class).
                  setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

 List claz = crit.list();

Vous pouvez également utiliser Criteria.DISTINCT_ROOT_ENTITY avec la requête Hibernate HQL.

Exemple:

Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();

J'ai eu quelques problèmes avec les transformateurs de résultats combinés avec les requêtes HQL. Quand j'ai essayé

final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);

cela n'a pas fonctionné. Je devais transformer manuellement comme ça:

final List found = trans.transformList(qry.list());

Avec l’API Criteria, les transformateurs fonctionnaient parfaitement.

Ma requête principale ressemblait à ceci dans le modèle:

@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd", 
    query = "select distinct i from CentralFinancialAgencyAccountCd i")

Et je n'obtenais toujours pas ce que je considérais comme "distinct". résultats. Ils étaient simplement distincts en fonction d’une combinaison de clés primaires sur la table.

Ainsi, dans le DaoImpl , j’ai ajouté un changement d’une ligne et obtenu le code "distinct". retour je voulais. Un exemple serait au lieu de voir 00 quatre fois je viens de le voir une fois. Voici le code que j'ai ajouté au DaoImpl :

@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {

    Session session = (Session) entityManager.getDelegate();
    org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
    q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
    List<CacheModelBase> codes;
    codes = q.list();
    return codes;       
}

J'espère que cela vous a aidé! Encore une fois, cela ne fonctionnera que si vous suivez les pratiques de codage qui implémentent le type de projet service, dao et modèle.

Supposons qu'une entité cliente soit mappée sur la table CUSTOMER_INFORMATION et que vous souhaitez obtenir la liste des prénoms distincts du client. Vous pouvez utiliser l'extrait ci-dessous pour obtenir le même.

Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();

J'espère que ça aide. Nous utilisons donc ici group by au lieu d'utiliser un mot clé distinct.

De même, j’ai trouvé difficile d’utiliser un mot clé distinct lorsque je souhaite l’appliquer à plusieurs colonnes. Par exemple, je veux obtenir une liste distincte de firstName, lastName puis group by fonctionnerait tout simplement. J'ai eu du mal à utiliser distinct dans ce cas.

Vous pouvez utiliser le même mot-clé dans votre générateur de critères, comme ceci.

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));

Et créez le constructeur de champ dans votre classe de modèle.

J'ai reçu une réponse permettant à Hibernate Query Language d'utiliser des champs distincts. Vous pouvez utiliser * SELECT DISTINCT (TO_CITY) FROM FLIGHT_ROUTE *. Si vous utilisez la requête SQL , elle renvoie la liste des chaînes. Vous ne pouvez pas utiliser la valeur renvoyée par classe d'entité. La solution pour résoudre ce type de problème consiste donc à utiliser HQL avec SQL .

FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);

À partir de l'instruction de requête SQL , il a reçu DISTINCT ROUTE_ID et entré sous forme de liste. Et la requête IN filtre le TO_CITY distinct de IN (Liste).

Le type de retour est le type de bean Entity. Donc, vous pouvez le faire en AJAX tel que AutoComplement .

Peut-être que tout soit OK

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top