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 :

[mapping] Entité ManyToMany avec un attribut supplémentaire.


Sujet :

Hibernate Java

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    student
    Inscrit en
    Janvier 2019
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : student

    Informations forums :
    Inscription : Janvier 2019
    Messages : 66
    Points : 34
    Points
    34
    Par défaut [mapping] Entité ManyToMany avec un attribut supplémentaire.
    Bonsoir à tous,

    alors ce sujet est une continuité de https://www.developpez.net/forums/d2...nytomany-meme/

    Mais, elle est légèrement différentes car nous n'avons plus de ManyToMany ...
    J'ai désormais ceci :

    La classe ChoixId qui sert à schématiser la clé composite:
    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
     
    //Classe servant à créer la clé composite de la table choix
    @Embeddable
    public class ChoixId implements Serializable {
     
        //Représentation de la clé composite
     
        // Liste des id des chapitres suivants possibles
        @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        @JoinColumn(foreignKey=@ForeignKey(name="choix_chapitre_suivant_fk")) //utilisation de la contrainte de la base
        private Chapitre suivant;
     
        // Liste des id des chapitres menants au chapitre en court
        @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        @JoinColumn(foreignKey=@ForeignKey(name="choix_chapitre_origine_fk")) //utilisation de la contrainte de la base
        private Chapitre origine;
     
        /////////////Fin de la clé composite
    }
    La classe Choix qui schématise ce qui reste de la table dans la BDD :
    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
     
    //Classe modélisant la table choix pour une utilisation du ManyToMany retravaillée
    @Entity
    @Table(name = "choix")
    @AssociationOverrides({ //ATTENTION !!! cette ensemble est indispensable pour faire la clé composite (ce qui permet ensuite d'afficher le nomchoix)
            @AssociationOverride(name = "id.origine",
                    joinColumns = @JoinColumn(name = "chap_origine")),
            @AssociationOverride(name = "id.suivant",
                    joinColumns = @JoinColumn(name = "chap_suivant")) })
    public class Choix {
     
        //clé composite => qui est représentée dans la classe ChoixId
        @EmbeddedId
        private ChoixId id = new ChoixId();
     
        //attribut supplémentaire de la table
        @Column(name = "choix_nom")
        private String nomChoix;
     
     
        //////////////////////////////////////////////
        //les getter/setter
    La classe chapitre
    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
     
     
    @Entity
    @Table(name = "chapitre")
    public class Chapitre implements Serializable {
     
        @Id
        @Column(name = "chap_id")
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;
     
        @Column(name = "chap_titre")
        private String titre;
     
        @Column(name = "chap_type")
        private String type;
     
        //liaison avec livre
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "livre_id")
        private Livre livre;
     
     
        //Zone pour relation ManyToMany retravaillé
        //(pour récupérer l'attribut choix_nom plus tard dans la table choix)
     
        // Liste des chapitres suivants possibles => on utilise l'id du chapitre en court pour trouver les choix suivants
        @OneToMany(mappedBy = "id.origine", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        private Set<Choix> suivants = new HashSet<Choix>();
     
    //    //Commenté car non utile actuellement
    //    // Liste des chapitres menants à ce chapitre
    //    @OneToMany(mappedBy = "id.suivant", cascade = CascadeType.ALL)
    //    private Set<Choix> origines = new HashSet<Choix>();
     
        /////////////////Fin de la zone retravaillé
     
    //////////////////////////////////////
        //les getter/setter
    J'ai un résultat qui est pas mal, dans mon json :
    Nom : chapitre_suivant.png
Affichages : 100
Taille : 9,7 Ko

    Mais j'ai juste un problème => id : {}

    Je devrais pouvoir récupérer l'id du chapitre qui est présent dans la table. Mais il semblerait qu'il s'agisse de l'objet entier.

    J'arrive pas à mettre la main sur cet id ?

    Une petite idée ? ou un suggestion ?

    Ca fait 2 semaines que je suis dessus maintenant, j'aimerai bien réussir à trouver une solution ...

  2. #2
    Nouveau membre du Club
    Femme Profil pro
    student
    Inscrit en
    Janvier 2019
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : student

    Informations forums :
    Inscription : Janvier 2019
    Messages : 66
    Points : 34
    Points
    34
    Par défaut tentative ... mais non
    Salutation,

    bon, je donne une info, supplémentaire, j'ai rajouté les getter/setter pour la classe ChoixId, Mais c'est une catastrophe ...

    J'ai désormais j'ai mes URL qui ont complétement pété :
    Nom : chapitre_suivant_CASSE.png
Affichages : 63
Taille : 6,5 Ko

    J'aurai dû avoir quelque chose comme dans le message précédent...

    Par contre étonnamment, mon runner lui fait le taffe. Il est parfait :
    Nom : chapitre_suivant_CASSE_runner_OK.png
Affichages : 62
Taille : 29,2 Ko

    Je suis complétement perdue.

    Je ne vois vraiment pas pourquoi mes urls ne fonctionnent plus.

  3. #3
    Nouveau membre du Club
    Femme Profil pro
    student
    Inscrit en
    Janvier 2019
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : student

    Informations forums :
    Inscription : Janvier 2019
    Messages : 66
    Points : 34
    Points
    34
    Par défaut DTO
    Salutation,

    Alors ça y est j'ai fini par avoir ce que je voulais.

    Je mets les infos ici au cas où cela intéressait qq1.

    Il a fallut que je passe par un DTO.

    ChoixId
    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
     
    //Classe servant à créer la clé composite de la table choix
    @Embeddable
    public class ChoixId implements Serializable {
     
        //Représentation de la clé composite
     
        // Liste des id des chapitres suivants possibles
        @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        @JoinColumn(foreignKey=@ForeignKey(name="choix_chapitre_suivant_fk")) //utilisation de la contrainte de la base
        private Chapitre suivant;
     
        // Liste des id des chapitres menants au chapitre en court
        @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        @JoinColumn(foreignKey=@ForeignKey(name="choix_chapitre_origine_fk")) //utilisation de la contrainte de la base
        private Chapitre origine;
     
        /////////////Fin de la clé composite
     
        //////////////////////////////////////////////
        //les getter/setter pour récupérer les id
     
        public Chapitre getSuivant() {
            return suivant;
        }
     
        public void setSuivant(Chapitre suivant) {
            this.suivant = suivant;
        }
     
        public Chapitre getOrigine() {
            return origine;
        }
     
        public void setOrigine(Chapitre origine) {
            this.origine = origine;
        }
    }
    Choix
    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
    41
     
    //Classe modélisant la table choix pour une utilisation du ManyToMany retravaillée
    @Entity
    @Table(name = "choix")
    @AssociationOverrides({ //ATTENTION !!! cette ensemble est indispensable pour faire la clé composite (ce qui permet ensuite d'afficher le nomchoix)
            @AssociationOverride(name = "id.origine",
                    joinColumns = @JoinColumn(name = "chap_origine")),
            @AssociationOverride(name = "id.suivant",
                    joinColumns = @JoinColumn(name = "chap_suivant")) })
    public class Choix {
     
        //clé composite => qui est représentée dans la classe ChoixId
        @EmbeddedId
        private ChoixId id = new ChoixId();
     
        //attribut supplémentaire de la table
        @Column(name = "choix_nom")
        private String nomChoix;
     
     
        //////////////////////////////////////////////
        //les getter/setter des attributs restant dans la classe
     
        //retourne la clé complexe sous forme d'objet => id: {} dans le json
        /*public ChoixId getId() {
            return id;
        }
     
        public void setId(ChoixId id) {
            this.id = id;
        }*/
     
        public String getNomChoix() {
            return nomChoix;
        }
     
        public void setNomChoix(String nomChoix) {
            this.nomChoix = nomChoix;
        }
     
    }
    ChoixDto
    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
     
    /**
     * Classe permettant d'exposer des données au format JSON au front.
     */
    public class ChoixDto {
     
        private Integer suivantId;
        private String nomChoix;
     
        public Integer getSuivantId() {
            return suivantId;
        }
     
        public void setSuivantId(Integer suivantId) {
            this.suivantId = suivantId;
        }
     
        public String getNomChoix() {
            return nomChoix;
        }
     
        public void setNomChoix(String nomChoix) {
            this.nomChoix = nomChoix;
        }
    }

    Chapitre
    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
    @Entity
    @Table(name = "chapitre")
    public class Chapitre implements Serializable {
     
        @Id
        @Column(name = "chap_id")
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;
     
        @Column(name = "chap_titre")
        private String titre;
     
        @Column(name = "chap_type")
        private String type;
     
        //liaison avec livre
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "livre_id")
        private Livre livre;
     
     
        //Zone pour relation ManyToMany retravaillé
        //(pour récupérer l'attribut choix_nom plus tard dans la table choix)
     
        // Liste des chapitres suivants possibles => on utilise l'id du chapitre en court pour trouver les choix suivants
        @OneToMany(mappedBy = "id.origine", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        @JsonIgnoreProperties("chapitre")
        private Set<Choix> suivants = new HashSet<Choix>();
     
    //    //Commenté car non utile actuellement
    //    // Liste des chapitres menants à ce chapitre
    //    @OneToMany(mappedBy = "id.suivant", cascade = CascadeType.ALL)
    //    private Set<Choix> origines = new HashSet<Choix>();
     
        /////////////////Fin de la zone retravaillé
     
     
        public Integer getId() {
            return id;
        }
     
        public void setId(Integer id) {
            this.id = id;
        }
     
        public String getTitre() {
            return titre;
        }
     
        public void setTitre(String titre) {
            this.titre = titre;
        }
     
        public String getType() {
            return type;
        }
     
        public void setType(String type) {
            this.type = type;
        }
     
        //ajout de id du livre pour éviter le renvoi de toute la base dans le json
        public Livre getLivre(Integer livre_id) {
            return livre;
        }
     
        public void setLivre(Livre livre) {
            this.livre = livre;
        }
     
     
        //////////////////////////////////////
        //les getter/setter du ManyToMany retravaillé
     
        public Set<Choix> getSuivants() {
            return suivants;
        }
     
        public void setSuivants(Set<Choix> suivants) {
            this.suivants = suivants;
        }
     
    //    //Commenté car non utile actuellement
    //    public Set<Choix> getOrigines() {
    //        return origines;
    //    }
    //
    //    public void setOrigines(Set<Choix> origines) {
    //        this.origines = origines;
    //    }
    }
    ChoixRepository
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    @Repository
    public interface ChoixRepository extends JpaRepository<Choix, Integer> {
     
        //récupérer le choix et son nom
        @Query(value = "SELECT chap.*, ch.* FROM choix ch, chapitre chap WHERE ch.chap_origine = :idOrigine AND chap.chap_id = ch.chap_origine", nativeQuery = true)
        Set<Choix> lesChoixPossibles(@Param("idOrigine") Integer idOrigine);
     
        //récupérer le choix et son nom
        @Query(value = "SELECT chap.*, ch.* FROM choix ch, chapitre chap WHERE ch.chap_origine = :idOrigine AND ch.chap_suivant = :idSuivant AND chap.chap_id = ch.chap_suivant", nativeQuery = true)
        Choix nomChoixPossible(@Param("idOrigine") Integer idOrigine, @Param("idSuivant") Integer idSuivant);
     
    }
    ChapitreRepository
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    @Repository
    public interface ChapitreRepository extends JpaRepository<Chapitre, Integer> {
     
        //requête native : on utilise la table = requête SQL
        //trouver 1 chapitre d'1 livre
        @Query(value = "SELECT c.* FROM chapitre c WHERE c.livre_id = :idL AND c.chap_id = :idC", nativeQuery = true)
        Chapitre findTheChapitreOfLivre(@Param("idL") Integer idL, @Param("idC") Integer idC);
     
        //afficher les choix de chapitre suivant
        @Query(value = "SELECT chap.*, ch.* FROM choix ch, chapitre chap WHERE ch.chap_origine = :idC AND chap.chap_id = ch.chap_suivant", nativeQuery = true)
        Set<Chapitre> chapitresSuivant(@Param("idC") Integer idC);
    }
    ChapitreController
    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
     
    @RestController
    @RequestMapping(value = "/chapitre")
    public class ChapitreController {
     
        @Autowired
        private ChapitreRepository chapitreRepository;
     
        @Autowired
        private ChoixRepository choixRepository;
     
     
        ////////////////////////
     
        //Utilisation du DTO : actuellement affichage d'un choix possible
        @RequestMapping(
                value = "/{idC}/choix",
                method = RequestMethod.GET,
                produces = "application/json"
        )
        public ResponseEntity<Set<ChoixDto>> afficherLeschoix(
                @PathVariable(value = "idC") Integer idC
        ){
            Set<Chapitre> listeChapitrePossible = chapitreRepository.chapitresSuivant(idC);
     
            Set<ChoixDto> listeChoixDto = new HashSet<ChoixDto>();
     
            for (Chapitre chap : listeChapitrePossible){
                Choix choix = choixRepository.nomChoixPossible(idC, chap.getId());
     
                ChoixDto dto = new ChoixDto();
                dto.setSuivantId(chap.getId());
                dto.setNomChoix(choix.getNomChoix());
     
                listeChoixDto.add(dto);
            }
            return ResponseEntity.ok(listeChoixDto);
        }
    Désormais j'ai bien mes choix qui sont proposés avec l'id du chapitre suivant



    Voilà ce que me rend l'url chapitre/4/choix
    Nom : chapitre_ses_choix.png
Affichages : 56
Taille : 4,8 Ko


    C'est les informations que je souhaitais récupérer pour les utiliser dans le formulaire de choix.

    ==============================

    Remarque : le passage par le DTO permet de choisir / fabriquer une sorte de template de ce que l'on souhaite vraiment afficher et qui peut être différents des informations présentes dans une seule table.

    Voilà si ça peut aider qq1

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [mapping] Entité avec un ManyToMany sur elle même
    Par pitchounvivi dans le forum Hibernate
    Réponses: 7
    Dernier message: 18/03/2021, 11h55
  2. [2.x] Doctrine v~2.2 | manyToMany avec attributs supplémentaires
    Par foolib dans le forum Symfony
    Réponses: 1
    Dernier message: 24/03/2015, 17h15
  3. [2.x] ManyToMany avec attribut, erreur à la création d'une entité
    Par Warnershoot dans le forum Symfony
    Réponses: 5
    Dernier message: 19/06/2012, 14h01
  4. Réponses: 8
    Dernier message: 25/10/2011, 10h18
  5. ManyToMany avec des colonnes supplémentaires
    Par melye dans le forum JPA
    Réponses: 2
    Dernier message: 23/06/2011, 10h15

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