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 :

Mapper les id de tables différentes avec un seul id dans une table "Label" ?


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    gnome
    Inscrit en
    Octobre 2004
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : El Salvador

    Informations professionnelles :
    Activité : gnome

    Informations forums :
    Inscription : Octobre 2004
    Messages : 142
    Par défaut Mapper les id de tables différentes avec un seul id dans une table "Label" ?
    Bonjour,

    J'ai une table label qui contient, en plus de sa clé primaire et du label, un id qui peut pointer vers l'une des quatre autres tables de la base. En effet, ma table label peut indifféremment contenir les libellés de chacune des autres tables.

    Or le mapping OneToOne exige de fixer, dans l'entité "Label", le type de l'objet lié par ledit mapping :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    @OneToOne(mappedBy = "destObject")
    private Personne personne;
    (ici la table labels ne pourra contenir que les labels de la table "Personne")

    Comment puis-je mapper ce type d'association ?

    Je ne sais pas si ce que je dis est compréhensible !

    Merci de votre aide.

    Pascal

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 964
    Par défaut
    Citation Envoyé par Bobsinglar Voir le message
    Bonjour,

    J'ai une table label qui contient, en plus de sa clé primaire et du label, un id qui peut pointer vers l'une des quatre autres tables de la base. En effet, ma table label peut indifféremment contenir les libellés de chacune des autres tables.

    Or le mapping OneToOne exige de fixer, dans l'entité "Label", le type de l'objet lié par ledit mapping :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    @OneToOne(mappedBy = "destObject")
    private Personne personne;
    (ici la table labels ne pourra contenir que les labels de la table "Personne")

    Comment puis-je mapper ce type d'association ?

    Je ne sais pas si ce que je dis est compréhensible !

    Merci de votre aide.

    Pascal
    inverser le discours :
    c'est la Personne qui a des Label et non le Label qui appartient à différentes tables…

    exemple pour supporter des Labels en plusieurs langues, dans Personne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        @OneToMany(cascade=CascadeType.ALL)
        @MapKey(columns=@Column(name="language", length=6))
        @JoinTable(name="PERSON_LABELS",
    		joinColumns= @JoinColumn(name="ref_person"),
    		inverseJoinColumns = @JoinColumn(name = "ref_label"))
        protected java.util.Map<String,Label>    hasLabels = new HashMap<String,Label>() ;
    pour chaque table XXX qui doit avoir des Label vous aurez une table de jointures XXX_LABELS…


    pour ajouter un label :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    hasLabels.put( "fr", new Label("fr", "exemple") ) ;
    hasLabels.put( "en", new Label("en", "example") ) ;
    (si vous voulez absolument garder votre idée originale, il y a une possibilité :
    toutes les entités pointées par Label doivent être des sous-classes d'une même classe et Label doit pointer sur la classe ancêtre… mais vous rencontrerez vite des limitations pour évoluer…)

  3. #3
    Membre confirmé
    Profil pro
    gnome
    Inscrit en
    Octobre 2004
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : El Salvador

    Informations professionnelles :
    Activité : gnome

    Informations forums :
    Inscription : Octobre 2004
    Messages : 142
    Par défaut
    Bonjour,

    Merci de votre réponse.
    Effectivement, après avoir posté, j'en étais arrivé à la conclusion qu'il fallait faire hériter les classes entités d'une classe commune, sans savoir si Hibernate pouvait accepter celà.

    Concernant votre première solution, avoir une table intermédiaire pour chaque table traduite me semble lourd.

    J'envisage plutôt d'essayer la seconde. Mais quelle limitations vais-je rencontrer ? Seulement la nécessité de la superclasse, ou plus ? Qu'aviez-vous en tête en écrivant celà ?

    Merci encore.

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 964
    Par défaut
    Citation Envoyé par Bobsinglar Voir le message
    Bonjour,

    Concernant votre première solution, avoir une table intermédiaire pour chaque table traduite me semble lourd.
    à voir en fonction des besoins, du contexte de l'application : cela a le mérite de fonctionner sans imposer de contrainte d'inhéritance et cela permet facilement la localisation en différentes langues…

    Citation Envoyé par Bobsinglar Voir le message
    Bonjour,
    J'envisage plutôt d'essayer la seconde. Mais quelle limitations vais-je rencontrer ? Seulement la nécessité de la superclasse, ou plus ? Qu'aviez-vous en tête en écrivant celà ?
    a. chaque fois qu'une nouvelle entité aura besoin de labels soit elle devra hérité de la superclasse (et si pour une autre raison business elle devrait aussi hérité d'une autre classe : les problèmes de refactoring peuvent surgir…) ou il faudra avoir 2 hiérarchies avec chacune leur système de label…

    b. le choix de la stratégie d'héritage (JOINED, TABLE_PER_CLASS, etc.) : chaque méthode a ses avantages et ses inconvénients qui sont bien expliqués dans la doc d'Hibernate (et des autres ORM…) et qui par ailleurs ont des conséquences spécifiques au RDBMS sous-jacent (par exemple le LOCK des tables en stratégie JOINED…)
    et ça c'est souvent beaucoup moins bien expliqué voire pas du tout…

  5. #5
    Membre confirmé
    Profil pro
    gnome
    Inscrit en
    Octobre 2004
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : El Salvador

    Informations professionnelles :
    Activité : gnome

    Informations forums :
    Inscription : Octobre 2004
    Messages : 142
    Par défaut
    Je persiste à vouloir implémenter la méthode par héritage. Et je me heurte à des difficultés :

    Après survol de la doc de référence hibernate-annotations (jusques là j'utilisais le tutoriel de Serge Tahé), j'en déduis que pour répondre à mes attentes, je dois marquer la superclasse comme @MappedSuperclass (section 2.2.4.4 de la doc).

    En effet, cette classe (abstraite) ne me servira qu'à avoir des libellés communs entre les classes héritières et à être référencée dans la classe "LabelPack". Elle ne sera jamais instanciée et ne doit pas avoir de table correspondante en base :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @MappedSuperclass
    public abstract class TranslatedEntity implements Serializable{
    ...
    }
    Toutes ses propriétés seront repportées dans chacune des tables des classes entités qui en hériterons. Exemple de classe héritière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public class ContentTypeDisplayer extends TranslatedEntity implements Serializable{
     
    	@Id
    	@Column(nullable = false)
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private Long id;
     
    	@Column(nullable = false)
    	@Version
    	private int jpaVersion;
    ...
    Le problème est que si je déclare ma superclasse de cette manière, lorsque Hibernate trouve une référence à celle-ci dans la classe "LabelPack", il ne la reconnait pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    javax.persistence.PersistenceException: org.hibernate.AnnotationException: Unknown mappedBy in: org.ecoscope.icame.entities.LabelPack.translatedEntity, referenced property unknown: org.ecoscope.icame.entities.TranslatedEntity.labelPack
    [hibernatetool] org.hibernate.AnnotationException: Unknown mappedBy in: org.ecoscope.icame.entities.LabelPack.translatedEntity, referenced property unknown: org.ecoscope.icame.entities.TranslatedEntity.labelPack
    Le seul moyen d'arriver à compiler, c'est de rajouter l'annotation @Entity, mais alors la table correspondante à cette classe abstraite est créée

    Existe-t-il un moyen de répondre à ce cas de figure ?

    Je m'excuse si je suis un peu trop exigeant, sur une situation aussi particulière.

    Cordialement,

    Pascal

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 964
    Par défaut
    Citation Envoyé par Bobsinglar Voir le message
    Je persiste à vouloir implémenter la méthode par héritage. Et je me heurte à des difficultés :

    Après survol de la doc de référence hibernate-annotations (jusques là j'utilisais le tutoriel de Serge Tahé), j'en déduis que pour répondre à mes attentes, je dois marquer la superclasse comme @MappedSuperclass (section 2.2.4.4 de la doc).
    @MappedSuperclass rend les attributs de la superclasse persistents dans la sous-classe mais cela ne permet pas de référencer explicitement cette classe dans des relations : le @Id est dans les sous-classes…
    (et c'est lui qui sert à établir les foreign key évidemment…)

    Il faut travailler avec les @Inheritance(strategy=InheritanceType.SELECT_THE_RIGHT_ONE_FOR_YOUR_SITUATION)

    voir
    http://www.hibernate.org/hib_docs/re...heritance.html

    points
    9.1.5. Table per concrete class
    et
    9.1.6. Table per concrete class, using implicit polymorphism

    semblent assez proches de ce que vous cherchez…

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/05/2014, 12h37
  2. Réponses: 5
    Dernier message: 28/11/2011, 15h47
  3. Réponses: 5
    Dernier message: 11/10/2010, 10h16
  4. Réponses: 3
    Dernier message: 05/02/2010, 04h45

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