Récupération d'un objet, select distinct sur un champ

Résolu/Fermé
ImaSheep Messages postés 5 Date d'inscription mardi 29 janvier 2013 Statut Membre Dernière intervention 29 janvier 2013 - Modifié par ImaSheep le 29/01/2013 à 15:38
ImaSheep Messages postés 5 Date d'inscription mardi 29 janvier 2013 Statut Membre Dernière intervention 29 janvier 2013 - 29 janv. 2013 à 17:54
Bonjour,

je suis plutôt débutant avec hibernate, et je suis confronté à un problème bloquant.

Je résume la situation, je vais essayer d'être clair :

J'ai une vue dans ma base Oracle, comprenant 7 champs.

Voici le mapping de cette vue :

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping package="fr.ucanss.inscriptions.modele"> 
 <class name="OrganismeARepartir" table="ORGANISME_A_REPARTIR"> 
  <composite-id> 
   <key-property name="idOrga" column="ID_ORGA" /> 
   <key-property name="codeBranche" column="CODE_BRANCHE" /> 
  </composite-id> 
  <property name="codeDep" column="CODE_DEP" type="string"/> 
  <property name="nomOrga" column="NOM_ORGA" type="string"/> 
  <property name="crfOrga" column="CRFORGA" type="string"/> 
  <property name="idRegion" column="ID_REGION" type="integer"/> 
  <property name="codeRegime" column="CODE_REGIME" type="string"/> 
 </class> 
</hibernate-mapping> 


Jusqu'à présent je n'ai rencontré aucun problème pour la requèter, mais je suis aujourd'hui face à un problème. Et je poste ici en espérant avoir de l'aide :)

Ma requète
select o from OrganismeARepartir o where ....
récupère donc une liste d'Objet de type OrganismeARepartir, qui sert à alimenter une liste avec les champ Id_Orga, nom_Orga

Seulement en l'absence de paramêtre entré par l'utilisateur, il y à plusieurs fois les mêmes nom dans la liste. Normal me direz vous car la clé composite porte sur codeBranche et idOrga ! Et je cherche donc à éviter cela.

Ce que je souhaite c'est qu'en l'absence de branche saisie par l'utilisateur, la liste par défaut n'affiche pas de doublon au niveau du nom.

j'ai donc modifié ma requète

select distinct o.idorga from OrganismeARepartir o where ....


Sauf que la, évidement ca ne me retourne plus une liste d'objet, mais une liste de string, donc ça ne me va pas, car je ne peux pas remplir ma liste correctement.

Comment puis-je effectuer un distinct sur un champ et récupérer la liste d'objet dans son intégralité.

j'espère que j'ai été clair. :)



2 réponses

ImaSheep Messages postés 5 Date d'inscription mardi 29 janvier 2013 Statut Membre Dernière intervention 29 janvier 2013
29 janv. 2013 à 15:43
Mon but étant d'éviter de passer par un truc cra cra du style : on récupère toute la liste, puis on met les données dont on à besoin dans un Set<Hasmap<String,String>> , ect ...

Parce que c'est moche, et que ... bonjour les perfs :)
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
29 janv. 2013 à 16:47
Je n'y connais pas grand chose en BDD, mais d'un point de vue performance, est-ce que faire le "distinct" dans la requête ou le traitement (astucieux) de la liste obtenue, ça ne reviendrait pas finalement au même ?

Au lieu de faire un Set<Hasmap<String,String>> comme tu dis, moi je ferais un arbre TreeSet qui va enlever les doublons à l'aide d'un Comparator, grâce à ta "clé composite" même si je ne suis pas sûr de ce que c'est...

List<OrganismeARepartir> liste = // select ...

//  la clé composite porte sur codeBranche et idOrga

Comparator<OrganismeARepartir> comp = new Comparator<OrganismeARepartir>()
{
    @Override
    public int compare(OrganismeARepartir o1, OrganismeARepartir o2)
    {
        int n = (o1.codeBranche).compareTo(o2.codeBranche);
        
        if (n==0)
            return (o1.idOrga).compareTo(o2.idOrga);
        else
            return n;
    }
}

// la liste par défaut n'affiche pas de doublon

TreeSet set = new TreeSet(comp);
set.addAll(liste);

// alimenter une liste avec les champ Id_Orga, nom_Orga 

ArrayList<ObjetResultat> liste2 = new ArrayList<ObjetResultat>(set.size());

for (OrganismeARepartir o : set)
    liste2.add(new ObjetResultat(o.Id_Orga, nom_Orga));
0
ImaSheep Messages postés 5 Date d'inscription mardi 29 janvier 2013 Statut Membre Dernière intervention 29 janvier 2013
29 janv. 2013 à 17:25
Tout d'abord merci pour ta réponse.
Je dois avoué que je ne suis pas familier avec les treeset et comparator, et que je trouve ça très utile, avec de bonnes perf.

En revanche, l'algo que tu fournis trie la liste, mais ne supprime pas les doublons :-(
Je vais continuer de chercher dans cette direction, ca me semble le plus simple
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié par KX le 29/01/2013 à 17:46
S'il ne trie pas les doublons, c'est que je n'ai pas compris le principe de ta "clé composite".
Quand le comparateur renvoie 0, les deux éléments sont considérés égaux et un seul est stocké dans l'arbre. Donc si ça ne marche pas c'est que je n'ai pas comparé ce qu'il fallait.

D'après tes explications j'avais considéré que deux éléments étaient égaux si on avait codeBranche et idOrga égaux, mais si n'est pas ça il faut changer la méthode compare.

Remarque : le fait que les éléments sont triés est évident quand on connait la structure d'un arbre.
0
ImaSheep Messages postés 5 Date d'inscription mardi 29 janvier 2013 Statut Membre Dernière intervention 29 janvier 2013
29 janv. 2013 à 17:47
Après un petit coup de débug pour vérifier, le comparator ne renvoi jamais 0 , alors qu'il devrait... :/

C'est très étrange

List<OrganismeARepartir> list = getHibernateTemplate().findByNamedParam(requete.toString(), paramNames, values);
		
		System.out.println(list.size());
		
		Comparator<OrganismeARepartir> comp = new Comparator<OrganismeARepartir>()
				{
				    @Override
				    public int compare(OrganismeARepartir o1, OrganismeARepartir o2)
				    {
				        int n = (o1.getCodeBranche()).compareTo(o2.getCodeBranche());
				        
				        if (n==0)
				            return (o1.getIdOrga()).compareTo(o2.getIdOrga());
				        else
				            return n;
				    }
				};

		TreeSet set = new TreeSet(comp);
		set.addAll(list);
		
		List<OrganismeARepartir> list2 = new ArrayList( set );
		
		System.out.println(list.size());
		
		return list;
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié par KX le 29/01/2013 à 17:53
Quels sont les types renvoyés par getCodeBranche() et getIdOrga() ?
Parce qu'ils doivent être Comparable pour que ça fonctionne...
0
ImaSheep Messages postés 5 Date d'inscription mardi 29 janvier 2013 Statut Membre Dernière intervention 29 janvier 2013
29 janv. 2013 à 17:54
Je n'ai rien dit, en fait je dois être complétement idiot ... je n'ai pas fait attention à mon nom de variable que je return (list au lieu de list2)

Donc oui tout fonctionne, très bien, et je te remercie vraiment pour ton aide. Je penserai dorénavant à utiliser plus souvent le treeset qui est vraiment une très bonne méthode.

Encore merci pour ton aide
0