1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : octobre 2008
    Messages : 179
    Points : 172
    Points
    172

    Par défaut Peut-on réaliser une relation oneToOne avec plusieurs clefs étrangères de même type ?

    Bonjour,

    je ne suis pas certain que mon titre est clair, alors je vais détailler un peu plus ma question.
    Tout d'abord, il est important de préciser que je ne maîtrise pas du tout JPA et hibernate; mes connaissances à ce sujet sont purement empiriques et il me manque donc certainement des notions fondamentales. Je dois pourtant intervenir dessus, d'où des questions dont les réponses seront souvent triviales à des initiés!

    J'en viens donc à ma question.

    Je dispose d'une classe "Operation" qui possède plusieurs clefs de même type vers un objet de type "Promotion". Pour des raisons très spécifiques au projet, on ne peut pas changer ce fait.
    Celà ressemble à:
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    @Entity
    @Table(name = "operation")
    public class Operation {
     
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int                id;
     
        @OneToOne(cascade = CascadeType.ALL)
        @JoinColumn(name = "promotion_fk")
        private Promotion               promotion;
     
        @OneToOne(cascade = CascadeType.ALL)
        @JoinColumn(name = "promotion_interne_fk")
        private Promotion               privatePromotion;
     
        @OneToOne(cascade = CascadeType.ALL)
        @JoinColumn(name = "promotion_legale_fk")
        private Promotion               legalPromotion;
     
        // + getters/ setters
     
        }
     
     
    @Entity
    @Table(name = "promotion")
    public class Promotion {
        @Id
        @GeneratedValue
        private int     id;
     
        // ICI ce que je voudrais
     
        @OneToOne
        @MappedBy(???)
        Operation parentOperation;
     
        // + getters/ setters
        }
    Je voudrais pouvoir, depuis n'importe quelle promotion, trouver son parent.
    Est-il possible de réaliser cette relation sans changer la structure de la base, juste en jouant avec les annotations, voire en rajoutant un ou plusieurs champs.

    Je sais que celà est possible en créant des descendants de Promotion et en les typant, mais c'est une solution que je ne peux malheureusement pas mettre en œuvre (à cause principalement de l'impact sur le projet).

    Si quelqu'un(e) a idée, je suis tout ouï. Et en attendant, je vous remercie déjà de m'avoir lu jusque là!
    Roger l'Âne: le lapin devenu grand....
    _______________________________________________________________
    Développeur bio-informatique; spécialiste en rien, généraliste en tout.

    Capitan ! Capitan ! On a aperçu le Loup ! Il a pris d'assaut une chaise à porteurs, à l'aide d'un cul-de-jatte et d'un lapin !
    (Pavillon noir !, Alain Ayroles/Jean-Luc Masboux, éd. Delcourt, coll. Terres de Légendes, 1997, p. 18)

  2. #2
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 2 938
    Points : 3 925
    Points
    3 925

    Par défaut

    Oui techniquement c'est possible,il faut que tu mettes ton mappedBy du coté de l'entité propriétaire de la jointure, Promotion par exemple:
    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
     
    @Entity
    @Table(name = "promotion")
    public class Promotion {
        @Id
        @GeneratedValue
        private int     id;
     
        // ICI ce que je voudrais
     
        @OneToOne(mappedBy="parentLegalOperation")
        Operation parentLegalOperation;
     
        // + getters/ setters
        }
    Ensuite dans Promotion :
    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
    @Entity
    @Table(name = "promotion")
    public class Promotion {
        @Id
        @GeneratedValue
        private int     id;
     
        // ICI ce que je voudrais
     
        @OneToOne
        @JoinColumn(name = "promotion_legale_fk")
        Operation parentLegalOperation;
     
        // + getters/ setters
        }
    Et ainsi de suite. Ceci dit je pense qu'il y'a un souci de conception, normalement il ne devrait y avoir qu'une seule relation entre Operation et Promotion, et dans la Promotion il devait y avoir une colonne permettant de dire quel type de promotion il s'agit. Suppose que demain on rajoute ou supprime une promotion, tu seras obligé de reconcevoir tout ton mapping.Mais le pb de conception ne se situe pas au niveau mapping ORM, mais plutot au niveau physique. Voila voila
    Vous avez peut être hâte de réussir et il n'y a rien de mal à cela...
    mais la patience est aussi une vertu; l'échec vous l'enseignera certainement..."

  3. #3
    Membre expert
    Homme Profil pro
    Inscrit en
    septembre 2006
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : septembre 2006
    Messages : 2 474
    Points : 3 416
    Points
    3 416

    Par défaut

    La méthode la plus souple serait d'utiliser une Map :
    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
     
    @Entity
    @Table(name = "operation")
    public class Operation {
     
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int                id;
     
        @OneToMany(…,orphanRemoval=true)
        @ForeignKey(name="fk_oppromo",inverseName="fk_promo")
        @JoinTable([schema="SCHEMA_NAME",]name="OPPROMOS_JOIN_TABLE_NAME",
    		joinColumns= @JoinColumn(name="REF_OPERATION_FIELDNAME"),
    		inverseJoinColumns = @JoinColumn(name = "REF_PROMO_FIELDNAME"))
        private Map<PROMO_TYPE,Promotion> promotions ;
    …
    }
    mais cela implique que vous puissiez adapter le schéma.

    PROMO_TYPE dans ce cas peut être une String, un Integer, un enum… (ou un UserType, mais sans doute trop lourd pour ce cas simple).

  4. #4
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : octobre 2008
    Messages : 179
    Points : 172
    Points
    172

    Par défaut

    Merci de vos réponses.

    par contre, DevServlet, je n'ai pas compris ce que tu m'expliquais : est-ce que je me trompe ou est-ce que tu as bien utilisé par erreur deux fois la classe promotion , en omettant l'entité propriétaire : "opération"?


    Citation Envoyé par DevServlet Voir le message
    Ceci dit je pense qu'il y'a un souci de conception, normalement il ne devrait y avoir qu'une seule relation entre Operation et Promotion, et dans la Promotion il devait y avoir une colonne permettant de dire quel type de promotion il s'agit. ...
    Citation Envoyé par JeitEmgie Voir le message
    La méthode la plus souple serait d'utiliser une Map
    ...
    mais cela implique que vous puissiez adapter le schéma.
    Je suis d'accord avec vous deux, mais lorsqu'on intervient comme pompier, on n'a pas toujours la possibilité de reconstruire le bâtiment. Il faut parfois faire au moins mal à défaut de faire au mieux.
    Roger l'Âne: le lapin devenu grand....
    _______________________________________________________________
    Développeur bio-informatique; spécialiste en rien, généraliste en tout.

    Capitan ! Capitan ! On a aperçu le Loup ! Il a pris d'assaut une chaise à porteurs, à l'aide d'un cul-de-jatte et d'un lapin !
    (Pavillon noir !, Alain Ayroles/Jean-Luc Masboux, éd. Delcourt, coll. Terres de Légendes, 1997, p. 18)

  5. #5
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 2 938
    Points : 3 925
    Points
    3 925

    Par défaut

    Citation Envoyé par DevServlet Voir le message
    Oui techniquement c'est possible,il faut que tu mettes ton mappedBy du coté de l'entité propriétaire de la jointure, Promotion par exemple:
    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
     
    @Entity
    @Table(name = "operation")
    public class Operation{
        @Id
        @GeneratedValue
        private int     id;
     
        // ICI ce que je voudrais
     
        @OneToOne(mappedBy="parentLegalOperation")
        Promotion parentLegalPromotion;
     
        // + getters/ setters
        }
    Ensuite dans Promotion:
    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
    @Entity
    @Table(name = "promotion")
    public class Promotion{
        @Id
        @GeneratedValue
        private int     id;
     
        // ICI ce que je voudrais
     
        @OneToOne
        @JoinColumn(name = "promotion_legale_fk")
        Operation parentLegalOperation;
     
        // + getters/ setters
        }
    Et ainsi de suite. Ceci dit je pense qu'il y'a un souci de conception, normalement il ne devrait y avoir qu'une seule relation entre Operation et Promotion, et dans la Promotion il devait y avoir une colonne permettant de dire quel type de promotion il s'agit. Suppose que demain on rajoute ou supprime une promotion, tu seras obligé de reconcevoir tout ton mapping.Mais le pb de conception ne se situe pas au niveau mapping ORM, mais plutot au niveau physique. Voila voila
    Autant pour moi. J'ai corrigé. Effectivement je te comprends, et c'est d'ailleurs j'ai bien ciblé le souci de conception en disant qu'il venait de la base.Sur laquelle tu n'aurais pas forcément une large manœuvre.Tiens nous au courant
    Vous avez peut être hâte de réussir et il n'y a rien de mal à cela...
    mais la patience est aussi une vertu; l'échec vous l'enseignera certainement..."

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/06/2012, 11h00
  2. Formulaire avec une relation oneToOne
    Par laupas dans le forum Doctrine2
    Réponses: 4
    Dernier message: 11/04/2012, 00h06
  3. probleme avec une relation OneToOne
    Par aniss77 dans le forum JPA
    Réponses: 1
    Dernier message: 01/04/2010, 22h07
  4. comment peut-on réaliser une communication usb avec un MC moto ?
    Par Super2006 dans le forum Périphériques
    Réponses: 10
    Dernier message: 25/03/2007, 22h38
  5. [ADO.NET]Comment réaliser une relation sur plusieurs champs?
    Par kleomas dans le forum Accès aux données
    Réponses: 3
    Dernier message: 13/03/2006, 12h40

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