IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JPA Java Discussion :

@ManyToMany : Table d'association sans clé composite avec List, pourquoi ?


Sujet :

JPA Java

  1. #1
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut @ManyToMany : Table d'association sans clé composite avec List, pourquoi ?
    Bonjour à tous !

    J'aimerais que quelqu'un m'éclaire !
    Pourquoi quand j'utilise un Set pour mon mapping le script DDL génère bien la clé composé des deux id pour la table d'association en revanche quand j'utilise des List la clé n'est pas généré ? Pourquoi ?

    Car j'aimerais bien utilisé des List et pouvoir regénérer le script DDL au besoin sans ajouté cet clé à la main ...

    Merci d'avance

  2. #2
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut
    Est ce que quelqu'un aurait une idée car là je sèche ...
    Y a t il possibilité de forcer la clé primaire en utilisant des List ? car il est quand même plus pratique d'utilisé des List dans les JSP (du moins dans mon cas)

    Merci d'avance

  3. #3
    Membre confirmé
    Profil pro
    Developpeur
    Inscrit en
    Avril 2004
    Messages
    160
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Developpeur

    Informations forums :
    Inscription : Avril 2004
    Messages : 160
    Par défaut
    Citation Envoyé par garthos Voir le message
    Bonjour à tous !

    J'aimerais que quelqu'un m'éclaire !
    Pourquoi quand j'utilise un Set pour mon mapping le script DDL génère bien la clé composé des deux id pour la table d'association en revanche quand j'utilise des List la clé n'est pas généré ? Pourquoi ?

    Car j'aimerais bien utilisé des List et pouvoir regénérer le script DDL au besoin sans ajouté cet clé à la main ...

    Merci d'avance
    Quand tu parles de script DDL, tu te situes à quel niveau ? Car pour moi un Set c'est au niveau de la programmation, script DDL c'est au niveau conception et génération de la base.

    Ton mapping tu le définis à l'aide d'un outil ?
    Ce n'est pas à partir de DDL qu'on génère le mapping?

    A vous.

  4. #4
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut
    J'ai fait une conception full object, ensuite j'ai donc codé mon mapping et ensuite je génère le script pour la base via l'outils hbm2ddl.
    Donc j'ai conçu mes objets avant car a mon sens en POO il est plus logique de partir des objets et de générer la base après (c'est d'ailleurs ce qui est recommandé dans la doc d'hibernate) et justement le fait que j'utilise une List ou un Set n'a pas la même incidence sur le script sql généré.
    Voilà tout ! en espérant avoir été assez clair dans mon explication.

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par garthos Voir le message
    …justement le fait que j'utilise une List ou un Set n'a pas la même incidence sur le script sql généré…
    … ce qui est expliqué dans la documentation d'Hibernate…

    http://docs.jboss.org/hibernate/anno...r/html_single/

    entre autres le 2.2.5.3

    (… et la sémantique Set implique aussi que vous implémentiez correctement equals() et hashCode() de l'entité membre du Set…)

  6. #6
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut
    Bon j'ai parcouru la doc et je ne pige pas ...
    qu'est ce que ça va apporté que j'implémente equals et hashCode ?

    Car mon soucis est quand j'utilise des List à la place des Set

  7. #7
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par garthos Voir le message
    Bon j'ai parcouru la doc et je ne pige pas ...
    qu'est ce que ça va apporté que j'implémente equals et hashCode ?

    Car mon soucis est quand j'utilise des List à la place des Set
    La doc vous explique ce que fait Hibernate avec vos déclarations : que vous utilisiez List, Set,… et que vous définissiez "mappedBy" ou non, Hibernate interprète vos désirs différemment… par exemple il génèrera ou pas une table intermédiaire pour faire du OneToMany bidirectionnel ou non.

    Equals et hashCode concerne un autre problème lié à l'utilisation du Set que vous risquez de rencontrer plus tard :
    Un Set est un ensemble d'objets qui sont tous distincts 2 à 2 : la librairie Java pour tester si un objet est déjà dans le Set a donc besoin que equals et hashCode soient implémentés correctement.
    Dans le contexte d'un ORM si la PK est NULL - objet transient, non encore persisté - l'égalité doit donc se tester sur d'autres champs, et il n'y a que le designer de l'application qui peut savoir ce que signifie "être le même" pour une entité particulière. (Dans equals, si les PKs des 2 objets sont initialisées - les 2 objets déjà persistés - vous pouvez évidemment vous contentez de les comparer…)

    La remarque vise seulement à attirer votre attention sur ce point : ce n'est pas parce que Set résout une partie du problème que votre travail s'arrête là.
    Si vous n'implémentez pas equals et hashCode correctement votre code aura des problèmes plus tard… le risque est en particulier dans les situations d'update du contenu des Sets.

  8. #8
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut
    Ok je vois ce que vous voulez dire ...
    mais Set ne résout justement pas mon problème puisque je voudrais utilisé des List ... qui sont plus pratique (dans mon cas) pour une utilisation dans les JSP
    Je suis désolé mais j'ai un peu l'impression de tourné en rond sur ce problème ...

    Donc est il possible en utilisant des List pour un @ManyToMany d'avoir la table d'association avec la clé composé lorque je lance la génération DDL ? Est ce qu'il y a qqch a ajouté ?

    A l'heure actuel j'ai eu une piste sur un autre post et j'ai donc ajouté une uniqueConstraints sur ma joinTable en utilsant des List et donc le script généré me génère la table d'association avec une contrainte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unique(table1_id,table2_id)
    Mais je ne sais pas trop si c'est la bonne solution ....
    Qu'est ce que ça change par rapport a une primary key ? quel pourrait être l’éventuel impact ?

    Merci d'avance

  9. #9
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    avez-vous mis un @JoinTable avec le @ManyToMany ?

  10. #10
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut
    Oui tout à fait, j'ai qqch qui ressemble à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    @ManyToMany(fetch = FetchType.LAZY)
    	@JoinTable(name = "TL_TABLE1_TABLE2", catalog = "MA_BDD",
    				joinColumns = { @JoinColumn(name = "table1_id",
    								referencedColumnName = "id",
    								nullable = false,
    								updatable = false)},
    				inverseJoinColumns = { @JoinColumn(name = "table2_id",
    										referencedColumnName = "id",
    										nullable = false,
    										updatable = false)},
    				uniqueConstraints = @UniqueConstraint(columnNames={"table1_id", "table2_id"}))
    public List<MonObjet> getMesObjets() {
    		return this.mesObjets;
    	}
    et donc la table de liaison générer via hbm2ddl ressemble à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     create table MA_BDD.TL_TABLE1_TABLE2 (
            table1_id integer not null,
            table2_id integer not null,
            unique (table1_id, table2_id)
        ) ENGINE=InnoDB;
    par contre quand j'utilise Set et sans le uniqueConstraints donc qqch comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    @ManyToMany(fetch = FetchType.LAZY)
    	@JoinTable(name = "TL_TABLE1_TABLE2", catalog = "MA_BDD",
    				joinColumns = { @JoinColumn(name = "table1_id",
    								referencedColumnName = "id",
    								nullable = false,
    								updatable = false)},
    				inverseJoinColumns = { @JoinColumn(name = "table2_id",
    										referencedColumnName = "id",
    										nullable = false,
    										updatable = false)})
    public Set<MonObjet> getMesObjets() {
    		return this.mesObjets;
    	}
    ça me génère :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     create table MA_BDD.TL_TABLE1_TABLE2 (
            table1_id integer not null,
            table2_id integer not null,
            primary key (table1_id, table2_id)
        ) ENGINE=InnoDB;
    je précise que j'ai volontairement changé les noms des champs et base ....

    Donc est ce que l'uniqueConstraints est la bonne méthode ?
    je dirais que oui car a priori ça solutionne le problème de la contrainte qui disparaissait lors de l'utilisation de List
    mais bon j'aimerais bien être sûr car je passe de primary key à unique du coup, est ce que cela peut avoir un impact.

    Merci d'avance.

  11. #11
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    le uniqueConstraint est en effet la seule manière de contredire ce que vous dites à l'ORM en utilisant List :

    une List en Java contient des objets dont l'adresse mémoire est distincte (unicité par "==") mais n'a aucune contrainte sur le fait qu'ils doivent être distincts 2 à 2 par equals() contrairement au Set : et donc l'ORM ne propage évidemment pas cette "volonté non exprimée" via une contrainte d'unicité…

    La seule différence entre la contrainte "PK" et la contrainte "unique" étant que la première permettrait d'utiliser le couple de clés dans une FK…

    Donc si vous voulez cette contrainte avec List il ne vous reste que uniqueConstraints dans le @JoinTable pour l'exprimer.

    (et notez que List vous permettrait aussi d'utiliser @OrderBy ce que Set ne permet pas…)

  12. #12
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut
    Ok merci pour toute ces précisions !!!
    je pense que dans mon cas il est donc suffisant de passer par des List en ajoutant l'uniqueConstrainte surtout que ça me permet de beneficier de l'avantage des List dans les JSP (voir ce post)
    Je pense notamment à ce genre de notation pour afficher le 1er element d'une List qui ne marche pas avec Set :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ${article.images[0].url}
    =>image étant une list, si c'est un Set pas moyen car le Set n'est pas indexé

    autre petit chose vous dites :
    Citation Envoyé par JeitEmgie Voir le message
    (et notez que List vous permettrait aussi d'utiliser @OrderBy ce que Set ne permet pas…)
    Mais j'ai justement un @OrderBy que je fait sur le champ name (que je n'avais pas mis dans le code que je vous ai montrer) et qui marchait tout a fait avec Set (car avant le passage en List c'était un Set), c'est toujours bon à dire

    Sinon j'ai une autre question pour vous JeitEmgie car vous avez l'air bien caler sur le sujet !,
    est ce que peux vous la poser en privé ? ou créer éventuellement un nouveau post ?
    ça concerne toujours les manyToMany et criteria (JPA2.0), car ça fait un moment que j'essaye de mettre des criteres sur le manyToMany lors d'un find mais malheureusement sans succès et j'ai beau chercher sur le net je n'ai jamais trouvé d'exemple correspondant ... (actuellement j'ai contourné mais ça ne me satisfait pas vraiment)

    Merci d'avance

  13. #13
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    une List en Java contient des objets dont l'adresse mémoire est distincte (unicité par "==")
    Heu non absolument pas.
    Une list contient un ensemble d'objet, les object peuvent apparaitre en plusieurs exemplaires.
    Un Set garanti l'unicité.

    Il est donc normal avec un List qu'il n'y aie pas de contrainte PK sur la table d'association puisque l'on a voulu la non unicité.

    Je dirais que si votre problème et purement lié à l'interface graphique, le plus simple serait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    @ManyToMany(fetch = FetchType.LAZY)
    public Set<MonObjet> getMesObjets() {
    		return this.mesObjets;
    	}
    @Transient
    public List<MonObject> getMaListeObjets(){
        return new ArrayList(getMesObjets);
    }

  14. #14
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut
    Oui mais il me semble qu'il est préférable de rajouter une uniqueConstraints non ?
    car déjà ça évite d'avoir 2 méthodes ... je trouve dommage d'avoir une méthode qui renvoie un Set que je ne vais finalement pas utiliser ... non ?

  15. #15
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Heu non absolument pas.
    Une list contient un ensemble d'objet, les object peuvent apparaitre en plusieurs exemplaires.
    Juste ! Merci d'avoir corrigé...

    Ce qui reste important à retenir avec List c'est que l'unicité du côté du Many
    doit être gérée par le code :
    si sémantiquement parlant le business case exige un Set
    Il convient de s'assurer que les opérations induites par l'UI
    ne permettent pas de violer cette règle ni de se retrouver
    avec plusieurs exemplaires d'un objet identique (au sens equals())
    dans la DB.

    Et si le business case veut des listes pouvant contenir plusieurs fois le même
    objet alors l'implémentation bidirectionnelle avec table intermédiaire est
    la seule possible.

  16. #16
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut
    Sinon j'ai une autre question pour vous JeitEmgie et tchize_ car vous avez l'air bien caler sur le sujet !,
    est ce que peux vous la poser en privé ? ou créer éventuellement un nouveau post ?
    ça concerne toujours les manyToMany et criteria (JPA2.0), car ça fait un moment que j'essaye de mettre des criteres sur le manyToMany lors d'un find mais malheureusement sans succès et j'ai beau chercher sur le net je n'ai jamais trouvé d'exemple correspondant ... (actuellement j'ai contourné mais ça ne me satisfait pas vraiment) ?

    Merci d'avance

  17. #17
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par garthos Voir le message
    Sinon j'ai une autre question pour vous JeitEmgie et tchize_ car vous avez l'air bien caler sur le sujet !,
    est ce que peux vous la poser en privé ? ou créer éventuellement un nouveau post ?
    ça concerne toujours les manyToMany et criteria (JPA2.0), car ça fait un moment que j'essaye de mettre des criteres sur le manyToMany lors d'un find mais malheureusement sans succès et j'ai beau chercher sur le net je n'ai jamais trouvé d'exemple correspondant ... (actuellement j'ai contourné mais ça ne me satisfait pas vraiment) ?

    Merci d'avance
    si vous devez travailler régulièrement avec JPA, je vous conseille fortement
    "Pro JPA 2 - Mastering the Java Persistence API" chez APRESS
    il est très complet concernant ce genre de choses et en ce qui concerne l'API Criteria, il la couvre dans son chapitre 9 sur 35 pages.

    http://techbus.safaribooksonline.com.../9781430219569
    et les exemples peuvent être déchargés ici :
    http://www.apress.com/9781430219569
    il y en a 6 pour le chapitre sur l'API Criteria.

  18. #18
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut
    Ok merci pour cette référence je vais la commander dès mon retour ...
    En attendant est ce que je peux te demander de l'aide ?
    car je suis actuellement en Asie et je ne rentre en France que le mois prochain ... et comme ça m'arrangerai assez de trouver comment faire ...
    Si tu pouvez me renseigner ça serait super !

    Merci d'avance

  19. #19
    Membre très actif
    Inscrit en
    Juin 2005
    Messages
    210
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 210
    Par défaut
    En fait je viens de voir que tu m'avais déjà aiguiller sur le sujet sur ce post

    Mais après de nombreux essai je n'ai pas réussi avec cet histoire d'Any ... donc du coup comme je le disais plus haut j'ai contourné le problème mais j'avoue que ça me plairait bien d'y arriver !

    Donc si jamais tu as un exemple ! Je suis preneur !

    merci d'avance

Discussions similaires

  1. graphiques sans lien direct avec tables/requetes
    Par samtheh dans le forum VBA Access
    Réponses: 1
    Dernier message: 23/07/2007, 15h45
  2. [HIBERNATE] requete avec table d'association
    Par zybay dans le forum Hibernate
    Réponses: 1
    Dernier message: 14/06/2007, 12h59
  3. Réponses: 1
    Dernier message: 07/06/2007, 16h18
  4. Réponses: 9
    Dernier message: 15/03/2007, 00h02
  5. Table sans primary key avec Hibernate
    Par zizou771 dans le forum Hibernate
    Réponses: 1
    Dernier message: 28/02/2007, 15h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo