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 :

ManyToMany unidirectionnel avec 2 clefs primaire partageant un même champ (l'id du multi-"tenant")


Sujet :

Hibernate Java

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2021
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2021
    Messages : 2
    Points : 1
    Points
    1
    Par défaut ManyToMany unidirectionnel avec 2 clefs primaire partageant un même champ (l'id du multi-"tenant")
    Bonjour

    Je débute en JPA / Hibernate par un schéma multi-tenant.
    J'ai une base de données simplifiée comme ceci:
    • studies: tenant_id, study_id sont des cléfs privées
    • physicians: tenant_id, physician_id sont des cléfs privées
    • les 2 sont liées par une table studies_ord_phys:
      Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      CREATE TABLE registry.studies_ord_phys (
            tenant_id uuid NOT NULL,
            study_id uuid NOT NULL,
            physician_id uuid NOT NULL,
            CONSTRAINT pk PRIMARY KEY (tenant_id, study_id, physician_id) );

    où un examen ('study') peut avoir plusieurs médecins demandeurs ('ordering physician'), et un médecin demander plusieurs examens.
    Je n'ai pas besoin de lien bidirectionnel entre les examens et les médecins, et je n'en veux d'ailleurs pas parce que les examens ont également des 'médecins destinataires' qui pointent aussi vers la même table 'physicians'.

    Je ne trouve pas de moyen de lier correctement les physicians avec les studies.

    En Java, j'ai créé un ID 'embeddable' pour mes examens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Embeddable
    public class StudiesId implements Serializable {
        @Column(name = "tenant_id", nullable = false)
        private UUID tenantId;
        @Column(name = "id", nullable = false)
        private UUID id;
     
        public UUID getId() { return id; }
        public void setId(UUID id) { this.id = id; }
        ...
    Pareil pour le PhysicianId (qui contient aussi le tenantId et son id)
    La classe Physicians:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Entity
    @Table(name = "physicians", schema = "registry")
    public class Physicians {
        @EmbeddedId
        private PhysiciansId id;
     
        @Column(name = "name", nullable = false)
        private String name;
        ...
    et la classe Studies:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Entity
    @Table(name = "studies", schema = "registry")
    public class Studies {
        @EmbeddedId
        private StudiesId id;
        ...
     
        @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(
                name = "studies_ord_phys", schema = "registry",
                joinColumns = {@JoinColumn(name = "study_id"), @JoinColumn(name = "tenant_id")},
                inverseJoinColumns = {@JoinColumn(name = "physician_id"), @JoinColumn(name = "tenant_id")}
        )
        private Set<Physicians> ordPhys = new HashSet<>();
    Si j'utilise 2 @JoinColumns alors JPA se plaint que:
    Repeated column in mapping for collection: ...studies.ordPhys column: tenant_id
    Si j'utilise seulement un seul @JoinColumn pour joinColumns et inverseJoinColumns alors:
    Physicians from ...studies has the wrong number of column. should be 2
    En SQL c'est facile, je lie simplement studies LEFT JOIN studies_ord_phys USING (tenant_id, study_id) et studies_ord_phys LEFT JOIN physicians USING (tenant_id, physician_id)

    PS: mes tenants ne sont pas complètement séparés et donc la plupart du temps les requêtes se font sur un seul tenant, mais parfois elles se font sur tous les tenants.

    J'ai essayé
    • de dupliquer le tenant_id dans la table de jointure. Ca marche, je peux alors avoir 2 clefs primaires faites de 2 champs complètement distincts et JPA fonctionne. Mais je trouve cela triste de dupliquer le tenant_id juste pour JPA. Et surtout c'est totalement inefficace parce que je travaille avec Microsoft Citus en faisant du sharding sur le tenant_id ==> la jointure entre studies_ord_phys et physicians se fait avec le clone de tenant_id qui n'est donc pas la clef de sharding ==> super lent ...
    • d'ajouter updatable = false, insertable = false sur l'inverseJoinColumn. Ca marche pour la lecture avec un seul tenant_id dans la table de jointure. Mais l'écriture ne marche pas parce qu'Hibernate essaye d'insérer 4 valeurs dans cette table de jointure ne contenant que 3 colonnes.
    • de passer par une classe intermédiaire comme proposé par Baeldung à la section 4.2 de cet article mais j'ai la même erreur:
      Repeated column in mapping for entity: com.telemis.tfp.registry.modelspp.StudyOrdPhyLink column: tenant_id (should be mapped with insert="false" update="false")
      pour ma classe intermédiaire:
      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
          @Id
          Long id;
       
          @ManyToOne
          @JoinColumns({
                  @JoinColumn(name="tenant_id", referencedColumnName = "tenant_id"),
                  @JoinColumn(name="study_id", referencedColumnName = "id")
          })
          Studies studylink;
       
          @ManyToOne
          @JoinColumns({
                  @JoinColumn(name="tenant_id", referencedColumnName = "tenant_id"),
                  @JoinColumn(name="physician_id", referencedColumnName = "id")
          })
          Physicians physicianLink;


    D'avance, un tout grand merci pour votre aide !

  2. #2
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2021
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2021
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Personne n'a d'idée ?
    Comment gérez-vous dans Hibernate le multi-tenant avec cette clef 'tenant_id' appartenant à chaque clef primaire ?

    Merci !

Discussions similaires

  1. [1.x] Formulaire d'une table avec 2 clefs primaires
    Par floringg dans le forum Symfony
    Réponses: 2
    Dernier message: 04/07/2012, 15h45
  2. sqlite select sur table avec plusieurs clefs primaire
    Par Nono1nd dans le forum Android
    Réponses: 4
    Dernier message: 08/06/2012, 11h34
  3. Réponses: 2
    Dernier message: 15/06/2011, 14h10
  4. Problème avec une clef primaire
    Par marcbo dans le forum VBA Access
    Réponses: 14
    Dernier message: 23/03/2011, 11h16
  5. Création du scaffold avec double clef étrangère sur la même table
    Par BakaOnigiri dans le forum Ruby on Rails
    Réponses: 4
    Dernier message: 17/12/2009, 22h32

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