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

Hibernate Java Discussion :

Lien ManyToMany sans table de liaison?


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Homme Profil pro
    Développeur Java/Scala
    Inscrit en
    Octobre 2007
    Messages
    1 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Scala

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 086
    Par défaut Lien ManyToMany sans table de liaison?
    Bonjour


    Je suis débutant sur Hibernate et je n'arrive pas a faier ce que je veux...


    En tres gros j'ai deux table:

    Service:
    - Id
    - Nom du service
    - Type d'unité

    Unite:
    - Id
    - Type d'unité
    - Langue
    - Valeur


    Pour illustrer un peu mieux:
    * Type d'unité = par exemple DAY, HOUR, KO...
    * Langue = fr,en,es,de etc...
    * Valeur d'unité = pour type DAY par exemplee day, jour... (traduction du type dans la langue)



    En gros ce que je voudrais c'est faire une jointure sur le type d'unité entre les services et les unitées sans avoir a passer par une table intermediaire du genre (pk_service,pk_unite)


    Dans l'optimum j'aimerai pouvoir recuperer a partir d'un objet service une Map(String,Unit) ou la key serait la langue de l'unité... mais bon si vous savez deja comment retourner une liste d'unitées qui correspondent au type ca serait deja tres bien

    J'ai regardé longtemps sur internet mais j'ai du mal a comprendre ce que je dois faire...:
    - pas de table de liason = pas de @JoinColumn???
    - retour en map selon langue il faut utiliser @MapKey c'est ca ?

    Si vous pouviez m'eclairer ca serait sympa

  2. #2
    Membre averti
    Inscrit en
    Novembre 2003
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 47
    Par défaut
    On peut pas avoir de relation many to many sans table de jointure...

    http://www.hibernate.org/hib_docs/v3.../#associations

  3. #3
    Membre Expert
    Homme Profil pro
    Développeur Java/Scala
    Inscrit en
    Octobre 2007
    Messages
    1 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Scala

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 086
    Par défaut
    Ok merci pour la réponse finalement j'ai un peu tout changé et maintenant j'ai:


    Service *---1 TypeDunite 1---* Unite

    (donc une nouvelle classe type d'unité)


    Par contre j'ai un autre probleme j'explique:

    En gros j'ai les codes suivants:

    Dans service:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    @ManyToOne(fetch=FetchType.EAGER)
    	@JoinColumn(name="unit_type_id")
    	private UnitType unitType;
    Dans TypeDunite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    @Id
    @Column(name="unit_type_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long id;
     
    @OneToMany(mappedBy="unitType",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
    @MapKey(name="language")
    private Map<String, Unit> units;
    Dans Unite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "unit_type_id")
    private UnitType unitType;

    Concretement ca fait exactement ce que je voulais cad, quand je fais un find sur un Service, je peux faire .getUnitType pour recuperer un type d'unité, qui grace au fetch eager chopera par la meme occasion la liste d'unitées correspondantes sous forme de map<String(Language),Unite>



    Seulement mon probleme c'est que j'ai également sur chacun des modeles une classe abstraite qui surcharge la methode de Object equals par reflection

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    @Override // equals by reflection
        public boolean equals(Object obj) {
        	System.out.println("Class = " + obj.getClass().getName());
            return EqualsBuilder.reflectionEquals(this, obj,Constants.EXCLUDE_FIELDS);
        }

    J'appelle cette methode sur un Service et d'apres le debug que j'ai fais je me tape une stack exception parce qu'en gros:

    equals(service) appelle:
    equals(unitType) qui appelle pour chaque unit de la map:
    equals(unit)
    ...

    Le probleme c'est que comme chaque Unit de la map possede un attribut UnitType, et bien chaque unit rappelle un equals sur son unittype et on est dans une boucle infinie...


    Le truc c'est que dans mon application a aucun moment je ne vais avoir besoin, a partir de l'unité, de retrouver le type d'unité qui correspond... Je voulais savoir si il etait possible, au chargement d'un Unit, de ne pas remplir l'objet UnitType a l'intérieur (car il me sert a rien...)


    J'ai essayé de mettre le Fetch a LAZY (comme indiqué dans le code) mais ca ne semble pas marcher



    J'ai trouvé quelques alternatives comme mettre unitType en excluselist sur les types a tester en reflection, ou alors faire ca:

    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
    16
    17
    18
    19
        @Override // equals by reflection
        public boolean equals(Object obj) {
        	LOG.debug("equals method on type: " + obj.getClass().getName());
        	if ( obj.getClass() == Unit.class ) {
        		return equalsById(obj);
        	}
            return EqualsBuilder.reflectionEquals(this, obj,Constants.EXCLUDE_FIELDS);
        }
        // equals by id, can be usefull for some objets like Unit (infinite equal calls otherwise)
        public boolean equalsById(Object obj) {
        	if (this == obj) {
        		return true;
        	}
        	if (  !(obj instanceof AbstractModel)   ) {
        		return false;
        	}
        	AbstractModel castobj = (AbstractModel) obj;
        	return new EqualsBuilder().append(this.getId(), castobj.getId()).isEquals();
        }

    Mais bon je trouve pas ca forcement super propre, tant qu'a faire je prefere garder une reflection simple et ne pas pouvoir recuperer l'UnitType a partir de Unit


    Des suggestions?

  4. #4
    Membre averti
    Inscrit en
    Novembre 2003
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 47
    Par défaut
    Mon conseil degage ton truc de reflection ....Ecris un equals "normal" et un hashcode qui utilisent tout les 2 une clé metier (et non pas la pk de la table ca peut poser des problèmes avec les map et set). C'est vraiment important d'avoir un modele "simple" ... et d'eviter les "workaround".

    La reflection ca fout souvent la merde... Le code est pas tres clair, ca peut bousiller les possibilités de refactoring future car tres souvent tu hardcodes le nom d'un attribut/methode ds ton algo ..., parfois ca charge des graph entier d'objet ce qui peut potentiellement generer des milliers de requetes si tu utilises hibernate... Bref ca peut etre utile mais faut faire gaffe !

  5. #5
    Membre Expert
    Homme Profil pro
    Développeur Java/Scala
    Inscrit en
    Octobre 2007
    Messages
    1 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Scala

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 086
    Par défaut
    Oui je vois ce que tu veux dire


    Apres le truc c'est que quand t'as plein d'objets c'est quand meme plus sympa de faire de la reflection dans la classe abstraite facile a faire et pas trop embetant alors que si je dois faire un equals pour chaque objet..

    J'ai cependant la methode getId dans la classe abstraite, je peux faire un equals sur les Id (comme dans mon exemple d'ailleur) seulement je trouve ca un peu limite...


    Mais d'un autre coté c'est vrai que si je dois comparer des objets entre eux ca serait quand meme mieux si ca ne fesait pas 5000 requetes, je suis pas sur que ca soit utile de voir si tous les objets liés par fk a l'objet comparé sont également identiques entre eux... (ca semble plus ou moins logique a partir du moment ou ils ont la meme valeur de clé...)

  6. #6
    Membre averti
    Inscrit en
    Novembre 2003
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 47
    Par défaut
    Je connais pas le metier de ton application ... mais bon en general on utilise equals pour comparer 2 objets et non 2 objets + leurs compositions (graph objet) respective...

Discussions similaires

  1. Relation ManyToMany sans table de jointure
    Par amira dans le forum JPA
    Réponses: 4
    Dernier message: 14/05/2014, 08h51
  2. graphiques sans lien direct avec tables/requetes
    Par samtheh dans le forum VBA Access
    Réponses: 1
    Dernier message: 23/07/2007, 15h45
  3. [ACCESS] lien entre 2 tables mais sans intégrité référentielle
    Par Philippe PONS dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 13/06/2007, 21h33
  4. [VB.NET] ComboBox lien entre deux tables
    Par VDB1 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 15/07/2004, 12h15
  5. lien entre les table de paradox
    Par salim_intic1 dans le forum Bases de données
    Réponses: 2
    Dernier message: 13/05/2004, 16h00

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