Participer au site avec un Tip
Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Exemple d'un mapping complet

Mapping d'une relation d'héritage La gestion des cascades



Accès rapide :
Travaux Pratiques
La correction
La classe Article et son mapping JPA
La classe CommandLine et son mapping JPA
La classe Command et son mapping JPA
La classe Payment et son mapping JPA
La classe PaypalPayment et son mapping JPA
La classe CreditCardPayment et son mapping JPA
La classe User et son mapping JPA
La classe UserInformations et son mapping JPA
La classe Role et son mapping JPA
Un code test de notre mapping

Travaux Pratiques

Je ne sais pas trop ce que vous en pensez, mais moi j'ai déjà bien bosser à écrire toutes ces pages. En conséquence, je me repose un peu et maintenant c'est à vous de jouer (lol). Le diagramme UML suivant vous montre l'ensemble des classes que nous pourrions utiliser pour un site de vente en ligne. En fait, nous avons déjà pas mal travaillé sur certaines de ces classes dans les chapitres précédents : vous en reconnaîtrez certainement quelques-unes.

Diagramme UML des classes à mapper avec JPA

Ce que je vous demande c'est de me coder ces classes et d'y rajouter le mapping JPA pour respecter le modèle ci-dessus. Vous avez le droit de copier/coller certaines parties de code à partir des pages précédentes, mais si vous tapez tout sans copier de code, c'est encore mieux et cela prouvera que vous maîtriser bien le mapping JPA. Je suis sympa avec vous, je vous donne ci-dessous le code SQL de la base de données à utiliser.

-- ------------------------------------------------------------------------------
-- - Reconstruction de la base de données                                     ---
-- ------------------------------------------------------------------------------
DROP DATABASE IF EXISTS WebStore;
CREATE DATABASE WebStore;
USE WebStore;


-- -----------------------------------------------------------------------------
-- - Construction de la table des utilisateurs                               ---
-- -----------------------------------------------------------------------------
CREATE TABLE T_Users (
    idUser              int         PRIMARY KEY AUTO_INCREMENT,
    login               varchar(20) NOT NULL,
    password            varchar(20) NOT NULL,
    connectionNumber    int         NOT NULL DEFAULT 0
);

INSERT INTO T_Users (idUser, login, password) VALUES ( 1, 'Anderson',   'Neo' );
INSERT INTO T_Users (idUser, login, password) VALUES ( 2, 'Skywalker',  'Luke' );
INSERT INTO T_Users (idUser, login, password) VALUES ( 3, 'Plissken',   'Snake' );
INSERT INTO T_Users (idUser, login, password) VALUES ( 4, 'Ripley',     'Ellen' );
INSERT INTO T_Users (idUser, login, password) VALUES ( 5, 'Bond',       'James' );

SELECT * FROM T_Users;

-- -----------------------------------------------------------------------------
-- - Construction de la table des informations des utilisateurs                                                       ---
-- -----------------------------------------------------------------------------
CREATE TABLE T_UserInformations (
    idInformations  int      PRIMARY KEY AUTO_INCREMENT,
    idUser          int      NOT NULL REFERENCES T_Users(idUser),
    address         text,
    city            text,
    email           text,
    phoneNumber     text
);

INSERT INTO T_UserInformations (idUser, address, city, email, phoneNumber) 
VALUES ( 1, 'Inconnue', 'La matrice', 'neo@matrix.com', '1234567890' ),
       ( 2, 'rue du Faucon', 'L''étoile noire', 'luke@glaforce.wars', '0147258369' ),
       ( 3, '1997, Manhattan', 'New York', 'snake@carpenter.com', '9638527410' ),
       ( 4, 'Nostromo', 'La bas', 'ripley@nostromo.alien', '9876543210' ),
       ( 5, 'SIS Building', 'London', '007@mi6.uk', '7007007007' );

SELECT * FROM T_UserInformations;

-- -----------------------------------------------------------------------------
-- - Construction de la table des rôles                                      ---
-- -----------------------------------------------------------------------------

CREATE TABLE T_Roles (
    idRole       int         PRIMARY KEY AUTO_INCREMENT,
    roleName     varchar(20) NOT NULL
);

INSERT INTO T_Roles (roleName)
VALUES ('client'), ('admin'), ('stockManager');

SELECT * FROM T_Roles;

-- -----------------------------------------------------------------------------
-- - Construction de la table d'association T_Users/T_Roles                  ---
-- -----------------------------------------------------------------------------

CREATE TABLE T_Users_Roles_Associations (
    idUser   int    NOT NULL REFERENCES T_Users(idUser),
    idRole   int    NOT NULL REFERENCES T_Roles(idRole)
);

INSERT INTO T_Users_Roles_Associations 
VALUES (1, 2), (1, 3), (2, 1), (3, 1), (4, 1), (5, 2);

SELECT * FROM T_Users_Roles_Associations;

-- -----------------------------------------------------------------------------
-- - Construction de la tables des articles en vente                         ---
-- -----------------------------------------------------------------------------
CREATE TABLE T_Articles (
    idArticle           int         PRIMARY KEY AUTO_INCREMENT,
    description         varchar(30) NOT NULL,
    brand               varchar(30) NOT NULL,
    unitaryPrice        double      NOT NULL
);

INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'Souris',                  'Logitoch',             65 );
INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'Clavier',                 'Microhard',            49.5 );
INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'Systeme d''exploitation', 'Fenetres Vistouille',  150 );
INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'Tapis souris',            'ATP Formation',        5 );
INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'Cle USB 8 To',            'Syno',                 8 );
INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'Laptop',                  'PH',                   1199 );
INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'CD x 500',                'CETME',                250 );
INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'DVD-R x 100',             'CETME',                99 );
INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'DVD+R x 100',             'CETME',                105 );
INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'Batterie Laptop',         'PH',                   80 );
INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'Casque Audio',            'Syno',                 105 );
INSERT INTO T_Articles ( description, brand, unitaryPrice ) VALUES ( 'WebCam',                  'Logitoch',             755 );

SELECT * FROM T_Articles;

-- -----------------------------------------------------------------------------
-- - Construction des tables des commandes et des lignes de commandes        ---
-- -----------------------------------------------------------------------------
CREATE TABLE T_Commands (
    idCommand       int         PRIMARY KEY AUTO_INCREMENT,
    idUser          int         NOT NULL REFERENCES T_Users(idUser),
    commandDate     datetime    NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE T_CommandLines (
    idCommandLine   int     PRIMARY KEY AUTO_INCREMENT,
    idCommand       int     NOT NULL REFERENCES T_Commands(idCommand),
    idArticle       int     NOT NULL REFERENCES T_Articles(idArticle),
    quantity        int     NOT NULL
);

-- Une première commande
INSERT INTO T_Commands (idUser, commandDate) VALUES ( 2, now() ); 
INSERT INTO T_CommandLines (idCommand, idArticle, quantity) VALUES (1, 1, 5); 
INSERT INTO T_CommandLines (idCommand, idArticle, quantity) VALUES (1, 3, 3);

-- Une seconde commande, pour un admin
INSERT INTO T_Commands (idUser, commandDate) VALUES ( 1, now() ); 
INSERT INTO T_CommandLines (idCommand, idArticle, quantity) VALUES (2, 2, 4); 
INSERT INTO T_CommandLines (idCommand, idArticle, quantity) VALUES (2, 3, 1);
INSERT INTO T_CommandLines (idCommand, idArticle, quantity) VALUES (2, 4, 1);

-- -----------------------------------------------------------------------------
-- - Construction de la table des paiements                                  ---
-- -----------------------------------------------------------------------------

CREATE TABLE T_Payments (
    idPayment           int          PRIMARY KEY AUTO_INCREMENT,
    idCommand           int          NOT NULL REFERENCES T_Commands(idCommand),
    amount              double       NOT NULL,
    paymentDate         datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO T_Payments (idCommand, amount, paymentDate) 
VALUES ( 1, 775, now() ),
       ( 2, 353, now() );

SELECT * FROM T_Payments;

-- -----------------------------------------------------------------------------
-- - Construction de la table des paiements paypal                           ---
-- -----------------------------------------------------------------------------

CREATE TABLE T_PaypalPayments (
    idPayment           int          NOT NULL REFERENCES T_Payments(idPayment),
    accountNumber       varchar(30)
);

INSERT INTO T_PaypalPayments VALUES ( 1, 'A fake paypal account' );

SELECT * FROM T_PaypalPayments;

-- -----------------------------------------------------------------------------
-- - Construction de la table des paiements par cartes bleues                ---
-- -----------------------------------------------------------------------------

CREATE TABLE T_CreditCardPayments (
    idPayment           int          NOT NULL REFERENCES T_Payments(idPayment),
    cardNumber          char(24),
    expirationDate      varchar(5)
);

INSERT INTO T_CreditCardPayments VALUES ( 2, '1234 5678 9012 3456', '06/19' );

SELECT * FROM T_CreditCardPayments;
Fichier Database.sql

Codez aussi un petit exemple de chargement d'une commande pour vérifier que votre mapping fonctionne bien et que vous arrivez à charger toutes les données de votre mapping.

Bon courage.
PS: ne passez pas directement à la suite de ce document pour voir la correction. Jouez le jeu.

La correction

La classe Article et son mapping JPA

Je vous propose de traiter les différentes classes une par une. La plus simple est certainement la classe Article, car elle ne définit pas de relation sur d'autres éléments. En voici son code.

 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 
package fr.koor.webstore.business;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;


@Entity @Table(name="T_Articles")
public class Article {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int idArticle;
    
    private String description;
    
    private String brand;
    
    @Column(name="UnitaryPrice") private double price;
    
    
    public Article() {
        this( "unknown", "unknown", 0 ); 
    }
    
    
    public Article( String description, String brand, double unitaryPrice ) {
        super();
        this.setDescription( description );
        this.setBrand( brand );
        this.setUnitaryPrice( unitaryPrice );
    }
    

    public int getIdArticle() {
        return idArticle;
    }

    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        System.out.println( "setDescription");
        this.description = description.toLowerCase();
    }
    
    public String getBrand() {
        return brand;
    }
    
    public void setBrand(String brand) {
        System.out.println( "setBrand");
        this.brand = brand.toUpperCase();
    }
    
    public double getUnitaryPrice() {
        return price;
    }
    
    public void setUnitaryPrice(double price) {
        if ( price < 0 ) throw new RuntimeException( "Price must be positive" );
        System.out.println( "setUnitaryPrice");
        this.price = price;
    }
    
    
    public String toString() {
        return "[" + this.idArticle + "]: " + this.description + " de marque " +
               this.brand + " - " + this.price + " euros";
    }
    
}
La classe Article et son mapping JPA

La classe CommandLine et son mapping JPA

Ensuite, je vous propose de coder la classe CommandLine. Mais attention celle-ci ayant besoin de la classe Command, je vous propose de produire aussi cette dernière à vide afin d'éviter les erreurs de compilation. Voici donc le code de la classe CommandLine.

 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 
package fr.koor.webstore.business;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity @Table(name="T_CommandLines")
public class CommandLine {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int idCommandLine;
    
    @ManyToOne @JoinColumn(name="idCommand", nullable=false)
    private Command command;
    
    @ManyToOne() @JoinColumn(name="idArticle", nullable=false)
    private Article article;
    
    private int quantity;
    
    
    public CommandLine() {}
    
    public CommandLine( Article article, int quantity ) {
        this.setArticle( article );
        this.setQuantity( quantity );
    }

    public CommandLine( Article article, Command command, int quantity ) {
        this.setArticle( article );
        this.setCommand( command );
        this.setQuantity( quantity );
    }

    public int getIdCommandLine() {
        return idCommandLine;
    }

    public Command getCommand() {
        return command;
    }

    public void setCommand(Command command) {
        this.command = command;
    }

    public Article getArticle() {
        return article;
    }
    
    public void setArticle(Article article) {
        this.article = article;
    }
    
    public int getQuantity() {
        return quantity;
    }
    
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
    
    public String toString() {
        return this.idCommandLine + ": " + this.quantity + " x " + this.article;
    }
    
}
La classe CommandLine et son mapping JPA

La classe Command et son mapping JPA

On poursuit avec la classe Command : comme pour la classe précédente, cette classe est mise en relation avec les classes Payment et User. Encore une fois créez ces classes à vide histoire d'éviter, temporairement, les erreurs de compilation.

 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 
package fr.koor.webstore.business;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity  @Table(name="T_Commands")
public class Command {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int idCommand;
    
    @ManyToOne @JoinColumn(name="idUser", nullable=false)
    private User user;
    
    private Date commandDate;
    
    @OneToMany(targetEntity=CommandLine.class, mappedBy="command", cascade=CascadeType.ALL)
    private Set<CommandLine> lines = new HashSet<CommandLine>();
    
    @OneToOne( mappedBy = "command" )
    private Payment payment;
    
    public Command() {}
    
    public Command( User user, Date commandDate ) {
        this.setUser( user );
        this.setCommandDate( commandDate );
    }

    public int getIdCommand() {
        return idCommand;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
    
    public Date getCommandDate() {
        return commandDate;
    }
    
    public void setCommandDate(Date commandDate) {
        this.commandDate = commandDate;
    }
    
    public Set<CommandLine> getLines() {
        return lines;
    }

    public void setLines(Set<CommandLine> lines) {
        this.lines = lines;
    }
    
    public Payment getPayment() {
        return payment;
    }
    
    public void setPayment(Payment payment) {
        this.payment = payment;
    }

    public String toString() {
        double totalPrice = 0;
        StringBuilder builder = new StringBuilder();
        builder.append( "Commande de >> " ).append( this.user ).append( " - " )
                        .append( this.commandDate ).append( "\n" );
        for( CommandLine theLine : this.lines ) {
            builder.append( "\t" ).append( theLine ).append( "\n" );
            totalPrice += theLine.getQuantity() * theLine.getArticle().getUnitaryPrice();
        }
        builder.append( "    Prix total de la commande : " ).append( totalPrice ).append( " euros" );
        return builder.toString();
    }   
    
}
La classe Command et son mapping JPA

La classe Payment et son mapping JPA

Il nous faut maintenant gérer les classes relatives aux paiements. En analysant la définition des tables en bases de données, vous constaterez que la stratégie de mapping pour l'héritage qui est utilisée en base est la stratégie « Tables Jointes ». Voici donc le code de la classe Payment.

pour de plus amples informations sur les différentes stratégies de mapping de l'héritage, je vous renvoie vers le chapitre consacré à ce sujet.
 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 
package fr.koor.webstore.business;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table( name = "T_Payments" )
@Inheritance( strategy = InheritanceType.JOINED )
public abstract class Payment {

    @Id @GeneratedValue(strategy=GenerationType.SEQUENCE)
    private int idPayment = 0;
    
    @OneToOne  @JoinColumn( name="idCommand" )
    private Command command;
    
    private double amount = 0;
    
    private Date paymentDate = new Date();

    public Payment() {
    }

    public int getIdPayment() {
        return idPayment;
    }

    public void setIdPayment(int idPayment) {
        this.idPayment = idPayment;
    }

    public Command getCommand() {
        return command;
    }
    
    public void setCommand(Command command) {
        this.command = command;
    }
    
    public double getAmount() {
        return amount;
    }

    public void setAmount(double amount) {
        this.amount = amount;
    }

    public Date getPaymentDate() {
        return paymentDate;
    }

    public void setPaymentDate(Date paymentDate) {
        this.paymentDate = paymentDate;
    }

    @Override
    public String toString() {
        return "Payment: idPayment=" + idPayment + ", amount=" + 
               amount + ", paymentDate=" + paymentDate;
    }
    
}
La classe Payment et son mapping JPA

La classe PaypalPayment et son mapping JPA

Voici maintenant le code de la classe dérivée PaypalPayment.

 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 
package fr.koor.webstore.business;

import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

@Entity 
@Table( name = "T_PaypalPayments" )
@PrimaryKeyJoinColumn( name = "idPayment" )
public class PaypalPayment extends Payment {

    private String accountNumber = "unknown";
    
    public PaypalPayment() {
        super();
    }
    
    public String getAccountNumber() {
        return accountNumber;
    }
    
    public void setAccountNumber(String accountNumber) {
        this.accountNumber = accountNumber;
    }
    
    @Override
    public String toString() {
        return super.toString() + ", accountNumber=" + accountNumber;
    }
}
La classe PaypalPayment et son mapping JPA

La classe CreditCardPayment et son mapping JPA

Pour clore la hiérarchie d'héritage pour nos paiements, voici le code de la classe CreditCardPayment.

 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 
package fr.koor.webstore.business;

import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

@Entity 
@Table( name = "T_CreditCardPayments" )
@PrimaryKeyJoinColumn( name = "idPayment" )
public class CreditCardPayment extends Payment {

    private String cardNumber = "unknown";
    private String expirationDate = "mm/yy";
    
    public CreditCardPayment() {
        super();
    }
    
    public String getCardNumber() {
        return cardNumber;
    }
    
    public void setCardNumber(String cardNumber) {
        this.cardNumber = cardNumber;
    }
    
    public String getExpirationDate() {
        return expirationDate;
    }
    
    public void setExpirationDate(String expirationDate) {
        this.expirationDate = expirationDate;
    }
    
    @Override
    public String toString() {
        return super.toString() + ", cardNumber=" + cardNumber + ", expirationDate=" + expirationDate;
    }
}
La classe CreditCardPayment et son mapping JPA

La classe User et son mapping JPA

Passons maintenant à la gestion de l'utilisateur de l'application et de ses différentes informations. Pour commencer, voici le code de la classe User.

 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 
package fr.koor.webstore.business;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity @Table(name="T_Users")
public class User {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int idUser;
    private String login;
    private String password;
    private int connectionNumber;
    
    @OneToOne( mappedBy = "user" )
    private UserInformations userInformations;
    
    @ManyToMany 
    @JoinTable( name = "T_Users_Roles_Associations",
                joinColumns = @JoinColumn( name = "idUser" ),
                inverseJoinColumns = @JoinColumn( name = "idRole" ) )
    private Set<Role> roles = new HashSet<>();
            

    
    public User() { }
    
    public User( String login, String password, int connectionNumber ) {
        super();
        this.setLogin( login );
        this.setPassword( password );
        this.setConnectionNumber( connectionNumber );
    }

    
    public int getIdUser() {
        return idUser;
    }
    
    
    public String getLogin() {
        return login;
    }
    
    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    public int getConnectionNumber() {
        return connectionNumber;
    }
    
    public void setConnectionNumber(int connectionNumber) {
        this.connectionNumber = connectionNumber;
    }

    public UserInformations getUserInformations() {
        return userInformations;
    }
    
    public void setUserInformations(UserInformations userInformations) {
        this.userInformations = userInformations;
    }
    
    public Set<Role> getRoles() {
        return roles;
    }
    
    public String toString() {
        return this.idUser + ": " + this.login + "/" + this.password + " - " + this.connectionNumber + " connexion(s)";
    }
    
}
La classe User et son mapping JPA

La classe UserInformations et son mapping JPA

Voici maintenant le code de la classe UserInformations.

 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 
package fr.koor.webstore.business;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity @Table(name = "T_UserInformations")
public class UserInformations {

    @Id  @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int     idInformations;
    
    private String  address;
    
    private String  city;
    
    private String  email;
    
    private String  phoneNumber;
    
    @OneToOne @JoinColumn( name="idUser" )
    private User user;
    
    public UserInformations() {
        this( "unknown", "unknown", "unknown", "unknown" );
    }
    
    public UserInformations( String address, String city, String email, String phoneNumber ) {
        this.setAddress( address );
        this.setCity( city );
        this.setEmail( email );
        this.setPhoneNumber( phoneNumber );
    }
    
    public int getIdInformations() {
        return idInformations;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
    
    public String getCity() {
        return city;
    }
    
    public void setCity(String city) {
        this.city = city;
    }
    
    public String getEmail() {
        return email;
    }
    
    public void setEmail(String email) {
        this.email = email;
    }
    
    public String getPhoneNumber() {
        return phoneNumber;
    }
    
    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public User getUser() {
        return user;
    }
    
    public void setUser(User user) {
        this.user = user;
    }
    
    @Override
    public String toString() {
        return "\tidInformations=" + idInformations + "\n\taddress=" + address 
             + "\n\tcity=" + city + "\n\temail=" + email + "\n\tphoneNumber=" + phoneNumber + "\n";
    }
    
}
La classe UserInformations et son mapping JPA

La classe Role et son mapping JPA

Et voici la dernière classe de notre mapping : la classe Role.

 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 
package fr.koor.webstore.business;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity @Table(name="T_Roles")
public class Role {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int idRole;
    private String roleName;
    
    @ManyToMany
    @JoinTable( name = "T_Users_Roles_Associations",
                joinColumns = @JoinColumn( name = "idRole" ),
                inverseJoinColumns = @JoinColumn( name = "idUser" ) )
    private Set<User> users = new HashSet<>();
            

    
    public Role() {
        this.idRole = 0;
        this.roleName = "unknown";
    }
    
    public int getIdRole() {
        return idRole;
    }
    
    public void setIdRole(int idRole) {
        this.idRole = idRole;
    }
    
    public String getRoleName() {
        return roleName;
    }
    
    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
    
    public Set<User> getUsers() {
        return users;
    }
    
    @Override
    public String toString() {
        return "[" + this.roleName + "]";
    }
    
}
La classe Role et son mapping JPA

Un code test de notre mapping

Et pour finir, voici un petit exemple de test de différentes classes de votre mapping.

 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 
package fr.koor.webstore;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import fr.koor.webstore.business.Command;
import fr.koor.webstore.business.Role;

public class Console {

    public static void main(String[] args) throws Exception {
        EntityManagerFactory entityManagerFactory = null;
        EntityManager entityManager = null;
        
        try {
            
            entityManagerFactory = Persistence.createEntityManagerFactory("WebStore");
            entityManager = entityManagerFactory.createEntityManager();
        
            Command command = entityManager.find( Command.class, 2 );
            System.out.println( command );
            
            for( Role role : command.getUser().getRoles() ) {
                System.out.println( role );
            }
            
            System.out.println( command.getPayment() );

        } finally {
            if ( entityManager != null ) entityManager.close();
            if ( entityManagerFactory != null ) entityManagerFactory.close();
        }
    }
}
La classe Console permettant de tester votre mapping


Mapping d'une relation d'héritage La gestion des cascades