Aller au contenu

3 - ENTITE VIN : CLE PRIMAIRE COMPOSITE avec @IdClass (pinard03)

Création du projet pinard03

Pour ce projet, j’ai utilisé Lombok dont voici le lien pour découvrir comment l’installer pour Eclipse :

https://projectlombok.org/setup/eclipse

Vous pourrez l’ajouter à vos dépendances Gradle ou Maven et ajouter les annoatations suivantes pour la classe Vin.java :

@Entity
@IdClass(VinPK.class)
@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class Vin implements Serializable {

J’ai aussi utilisé un type enum pour le choix des couleurs du vin :

 public enum choix {ROUGE,BLANC,ROSE};
    
    @Enumerated(value = EnumType.STRING)
    @Column(length = 5)    
    private choix couleur;

Objectif : Créer une entité Vin avec une clef composite, c’est-à-dire une clef composée du codeProduit et de la designation.

@Entity
@IdClass(VinPK.class)
public class Vin implements Serializable {
}

Il faut l’annotation @Id devant le champ codeProduit ou la méthode getCodeProduit() :

   @Id
    public Integer getCodeProduit() {
        return this.codeProduit;
    }

ainsi que devant le champ designation ou la méthode getDesignation() :

    @Id
    public String getDesignation() {
        return designation;
    }

Dans le package fr.apprenant.model, créer ensuite la classe VinPK qui comportera les attributs suivants :

public class VinPK implements Serializable {
    private Integer codeProduit;
    private String designation;

Remarque : Si vous le faites seul(e), il faut penser à faire passer une clef de type VinPk et non plus seulement le codeProduit pour détruire ou mettre à jour une quantité dans le contrôleur. Voici un bout de code pour vous mettre sur la voie avec l’instanciation d’un Vin v1 dans le contrôleur :

Vin v4=new Vin();
v4.setCodeProduit(111111);
v4.setDesignation("Clos du Baron 1998");
v4.setRegion("Bordeaux (Saint-Julien)");
v4.setCouleur(choix.BLANC);
v4.setPrix(45.20);
v4.setRemise(0);
v4.setQuantite(50);
updateQuantite(new VinPK(v4.getCodeProduit(),v4.getDesignation()),40);

/**
 * Met à jour la quantité d'un objet de type Vin
*/
public void updateQuantite(VinPK vinPk, int quantite)
{
	(vinRepository.getOne(vinPk)).setQuantite(quantite);
}

Pour avoir un code respectant la notion de composant, vous pourriez réécrire ce contrôleur en créant une classe VinService pour y intégrer toutes les méthodes métiers et ainsi ne pas avoir autant de code dans la méthode String home(). Vous pourriez aussi remplir la table Vin avec un fichier data.sql dans le répertoire resources, à vous de faire les modifications (même si le code fonctionne) :

@GetMapping("/")
	@ResponseBody
	public String home(){
		
		Vin v1=new Vin();
		v1.setCodeProduit(777777);
		v1.setDesignation("Les Hauts du Tertre 1999");
		v1.setRegion("Bordeaux (Margaux)");
		v1.setCouleur(choix.ROUGE);
		v1.setPrix(11.50);
		v1.setRemise(0);
		v1.setQuantite(2);

		Vin v2=new Vin();
		v2.setCodeProduit(888888);
		v2.setDesignation("Château Marquis de Terme 1998");
		v2.setRegion("Bordeaux (Margaux)");
		v2.setCouleur(choix.BLANC);
		v2.setPrix(19.00);
		v2.setRemise(0);
		v2.setQuantite(3);

		Vin v3=new Vin();
		v3.setCodeProduit(999999);
		v3.setDesignation("Clos du Marquis 1999");
		v3.setRegion("Bordeaux (Saint-Julien)");
		v3.setCouleur(choix.ROUGE);
		v3.setPrix(22.90);
		v3.setRemise(0);
		v3.setQuantite(15);

		Vin v4=new Vin();
		v4.setCodeProduit(111111);
		v4.setDesignation("Clos du Baron 1998");
		v4.setRegion("Bordeaux (Saint-Julien)");
		v4.setCouleur(choix.BLANC);
		v4.setPrix(45.20);
		v4.setRemise(0);
		v4.setQuantite(50);


		System.out.println("ajout du produit v1 : "+v1);
		ajoutVin(v1);

		System.out.println("ajout du produit v2 : "+v2);
		ajoutVin(v2);

		System.out.println("ajout du produit v3 : "+v3);
		v3=ajoutVin(v3);
		v3.setQuantite(10);
		updateVin(v3);

		System.out.println("ajout du produit v4 : "+v4);
		v4=ajoutVin(v4);

		updateQuantite(new VinPK(v4.getCodeProduit(),v4.getDesignation()),40);

		StringBuilder sb = new StringBuilder();
		sb.append("<h1>Regardez dans votre console et dans votre base de données MySQL <strong>JPA</strong></h1>");
		sb.append("<a href='http://localhost:8080/vins'>Voir la liste des vins enregistrés</a>");
		return  sb.toString();
	}

	

	public Optional<Vin> findById(VinPK vinPk){
		return vinRepository.findById(vinPk);
	}
	/**
	 * Retourne tous les produits dans une liste
	 */
	@GetMapping("/vins")
	public Collection<Vin> findAll(){

		return vinRepository.findAll();
	}
	/**
	 * Ajoute un vin
	 */
	public Vin ajoutVin(Vin vin){
		return vinRepository.saveAndFlush(vin);
	}
	/**
	 * Met un jour un enregistrement pour un objet Vin
	 */
	public Vin updateVin(Vin vin){
		return vinRepository.saveAndFlush(vin);
	}


	/**
	 * Met à jour la quantité d'un objet de type Vin
	 */
	public void updateQuantite(VinPK vinPk, int quantite){
		(vinRepository.getOne(vinPk)).setQuantite(quantite);
	}

tp3-clef-composite-1.png

CREATE TABLE IF NOT EXISTS `vin` (
  `code_produit` int(11) NOT NULL,
  `designation` varchar(50) NOT NULL,
  `couleur` varchar(5) DEFAULT NULL,
  `prix` double NOT NULL,
  `quantite` int(11) NOT NULL,
  `region` varchar(45) DEFAULT NULL,
  `remise` double NOT NULL,
  PRIMARY KEY (`code_produit`,`designation`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Retour vers les autres exercices