10 juillet 2022 Hibernate Java JPA Spring Boot

JPA/Hibernate – Intégration d’une Clé primaire composite (@Embeddable, @EmbeddedId)

Dans cet exemple, nous allons apprendre à intégrer une clé primaire composite, nous allons déclarer les ID (champs de clé primaire) comme une classe distincte annotée de l’annotation @Embeddable. Un élève est identifié par son EleveCompositeId, qui est défini par eleveId et classe.

Pour savoir ce qu’est une clé composite, nous devons savoir ce qu’est une clé primaire, une clé primaire est une colonne qui a une valeur unique et non nulle dans une table SQL.

Maintenant, une clé composite est également une clé primaire, mais la différence est qu’elle est constituée par la combinaison de plusieurs colonnes pour identifier la ligne particulière dans la table.

Entrons dans le code…

Créez un simple projet Spring Boot « TutoHibernatePK »

Structure des dossiers :

Le fichier POM.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.autourducode</groupId>
    <artifactId>TutoHibernatePK</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>TutoHibernatePK</name>
    <description>TutoHibernatePK</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Créer les classes Java :

EleveCompositeId.java

package com.autourducode;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.io.Serializable;
import java.util.Objects;

/**
 * @author autourducode
 */
@Embeddable
public class EleveCompositeId implements Serializable {
    @Column(name = "ELEVE_ID")
    private int eleveId;
    @Column(name = "CLASSE", length = 50)
    private String classe;

    public EleveCompositeId() {
    }

    public int getEleveId() {
        return eleveId;
    }

    public void setEleveId(int eleveId) {
        this.eleveId = eleveId;
    }

    public String getClasse() {
        return classe;
    }

    public void setClasse(String classe) {
        this.classe = classe;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        EleveCompositeId that = (EleveCompositeId) o;
        return eleveId == that.eleveId && classe.equals(that.classe);
    }

    @Override
    public int hashCode() {
        return Objects.hash(eleveId, classe);
    }
}

Afin d’implémenter une clé composite dans Hibernate, nous devons surcharger les méthodes equals() et hashCode() et également implémenter l’interface Serializable. Notre classe EleveCompositeId agit en tant que classe d’identification et nous l’avons marquée avec l’annotation @Embeddable afin que cette classe soit éligible pour être une classe intégrable.

Eleve.java

package com.autourducode;

import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.Objects;

@Entity
@Table(name = "ELEVE")
public class Eleve {
    @EmbeddedId
    private EleveCompositeId eleveCompositeID;

    @Column(name = "NOM_ELEVE", length = 80)
    private String nomEleve;

    public Eleve() {
    }

    public EleveCompositeId getEleveCompositeID() {
        return eleveCompositeID;
    }

    public void setEleveCompositeID(EleveCompositeId eleveCompositeID) {
        this.eleveCompositeID = eleveCompositeID;
    }

    public String getNomEleve() {
        return nomEleve;
    }

    public void setNomEleve(String nomEleve) {
        this.nomEleve = nomEleve;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Eleve eleve = (Eleve) o;
        return eleveCompositeID.equals(eleve.eleveCompositeID) && nomEleve.equals(eleve.nomEleve);
    }

    @Override
    public int hashCode() {
        return Objects.hash(eleveCompositeID, nomEleve);
    }
}

Nos champs de clé primaire (eleveId et classe) sont définis dans notre classe intégrable (EleveCompositeId). La classe d’entité Eleve contient un seul champ de clé primaire (eleveCompositeID) qui est annoté avec @EmbeddedId et contient une instance de cette classe intégrable.

Le fichier application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/tutodb?serverTimezone=UTC
spring.datasource.username=autourducode
spring.datasource.password=autourducode

spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true

Création du shéma de la base de données

Après avoir démarré notre application, hibernate met à jour le schéma de la base de données

Hibernate: create table eleve (classe varchar(50) not null, eleve_id integer not null, nom_eleve varchar(80), primary key (classe, eleve_id)) engine=MyISAM

La combinaison de la colonne classe et eleve_id constitue une clé composite, elle sera utilisé pour identifier de manière unique chaque ligne de la table.

J’espère que cet article vous a été utile. Merci de l’avoir lu.

Retrouvez nos vidéos #autourducode sur notre chaîne YouTube : https://bit.ly/3IwIK04

    07.11.22 à 22 h 33 min

    L’implantation de l’interface Serialisable ne se fais pas automatiquement avec Spring boot doit-on encore spécifié.?

      admin
      07.14.22 à 17 h 21 min

      Oui, avec spring boot c’est optionnel, nous l’avons ajouté pour montrer l’importance de cette interface de manière générale dans l’utilisation de la JPA.
      Un exemple d’utilisation dans un environnement Java SE https://bit.ly/3AiD5J6

    07.29.22 à 18 h 57 min

    A fascinating discussion is definitely worth comment. I do think that you ought to publish more about this topic, it may not be a taboo subject but typically people dont speak about such issues. To the next! Many thanks!!

    08.01.22 à 20 h 39 min

    I must thank you for the efforts you have put in writing this blog. Im hoping to check out the same high-grade blog posts from you in the future as well. In fact, your creative writing abilities has encouraged me to get my own, personal site now 😉

Répondre à admin Annuler la réponse

Votre adresse e-mail ne sera pas publiée.