web-dev-qa-db-fra.com

HQL: Comment sélectionner toutes les entités distinctes par une colonne?



Une question simple:
Dans cet exemple, je dois extraire tous les objets, mais ces objets doivent avoir des champs msgFrom distincts.
Quand j'utilise

List<Message> list = getHibernateTemplate().find("select distinct m.msgFrom from Message m WHERE msgTo = ? AND msgCheck = 0", dinc);

J'ai l'erreur suivante: 

Java.lang.ClassCastException: Java.lang.Integer cannot be cast to com.example.model.Message

Je suppose que c'est parce qu'Hibernate ne récupère qu'une seule colonne, mais j'ai besoin d'un objet, pas d'une colonne. 
Comment puis-je faire ceci? 
Je pense que je peux simplement faire défiler une virgule, c.-à-d. 

List<Message> list = getHibernateTemplate().find("select distinct m.msgFrom, m.To, m.datetime, .......... from Message m WHERE msgTo = ? AND msgCheck = 0", dinc);

Mais que se passe-t-il si j'ai plus de 20 champs ici? Y a-t-il une solution facile?

Merci!

18
gennad

Voici l'exemple de requête:

select e from Message e 
where e.msgFrom IN (select distinct m.msgFrom 
                      from Message m
                      WHERE m.msgTo = ? 
                      AND m.msgCheck = "0");

Alternativement, vous pouvez également utiliser l'API Criteria.

17
Nayan Wadekar

Vous pouvez également utiliser les critères et la projection ensemble:

Criteria criteria = session.createCriteria( MyEntity.class );
criteria.setProjection( Projections.distinct( Projections.property( "id" ) ) );

J'espère que ça aidera quelqu'un.

26
Ashfak Balooch

Le critère Hibernate est assez facile pour sélectionner des résultats distincts . Si vous souhaitez qu'un résultat unique soit renvoyé dans le résultat projeté, vous pouvez utiliser:

Criteria criteria = session.createCriteria(Message.class);
criteria.setProjection(Projections.distinct(Projections.property("msgFrom ")));
List<String> msgFromList = criteria.list();

Si vous voulez que le résultat inclue toute la classe Message avec tout son jeu de propriétés, vous pouvez utiliser Hibernate result Transformer.

Criteria criteria = session.createCriteria(Message.class);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List<Message> messages = criteria.list();

Mais cela filtre sur la base de l'entité racine.

Ou

Criteria criteria = session.createCriteria(Message.class);

ProjectionList projection = Projections.projectionList();
projection.add(Projections.distinct(Projections.property("msgFrom")));
//Add as many columns as you want using Projection
projection.add(Projections.property("msgTo"));
criteria.setProjection(projection);

criteria.setResultTransformer(Transformers.aliasToBean(Message.class));
List<String> msgFromList = criteria.list();

Selon votre question, la première solution donne un résultat correct.

5
Kamal Singh

Essayez ceci, cela a fonctionné pour moi:

SELECT FROM YourTableName 
WHERE somecolumnName=condition 
GROUP BY yourDistinctColumnName
3
Harz

J'ai obtenu une réponse pour que Hibernate Query Language utilise des champs distincts. Vous pouvez utiliser SELECT DISTINCT(TO_CITY) FROM FLIGHT_ROUTE. Si vous utilisez une requête SQL, il retourne une liste de 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)";

De l'instruction de requête SQL, il a obtenu 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. Ainsi, vous pouvez le faire dans AJAX tel que le complément automatique.

Que tout soit ok

0
San Lin Naing