SlideShare une entreprise Scribd logo
1  sur  123
Author: Thibault Cuvillier – Creative Commons 2.0

Java Persistence API

Auteur: Thibault Cuvillier
Consultant indépendant
cuvillier@gmail.com
http://www.btcweb.com
JP 1.1 - Template 1.0
Contenu de la présentation
•
•
•
•
•
•

Chap
Chap
Chap
Chap
Chap
Chap

1:
2:
3:
4:
5:
6:

Introduction
Mapping objet relationnel – Niveau 1
EntityManager
EJBQL – Niveau 1
Mapping objet relationnel – Niveau 2
EJBQL – Niveau 2

• Les questions et corrigés des TP sont accessibles sur
mon site.
• JPA 1, TP avec Hibernate 3.1 et Eclipse (pas mavenifié…)
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

2
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

Introduction

JP 1.1 - Template 1.0
Introduction à javax.persistence
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

4
Accéder à la base de données
Session Http
• Les objets d'une application
1
peuvent être:
*
– Transitoires: ils ne survivent pas
Caddie
1
à l'application
*
– Persistants: ils survivent à l'application
Item
1
• Exemple: dans un système de
*
vente en ligne:
Produit
– La classe Caddie est transitoire,
ne contenant que des informations sur la session
– La classe produit est persistante dans une base de
données.
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

5
Les quatre modèles 1/2
transitoire

Le modèle conceptuel
La compréhension de l'utilisateur

Le modèle logique
Modèle objet

Le modèle de présentation
Les données présentées à l'utilisateur
Thibault Cuvillier
Creative Commons 2.0

Le modèle physique
Schéma de la base

javax.persistence / Introduction

6
Les quatre modèles 2/2
• Les quatre modèles doivent être isomorphes
– Intégration sémantique
• Les relations entre les modèles sont des
mappings
• Mapping entre le modèle logique et le schéma
d'une base de données relationnelle:
– Mapping Objet Relationnel

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

7
Le mapping objet-relationnel
• Décrit la projection d'une classe dans un SGRBR
• Exemple:
– Une classe = Une table
– Une propriété = Une colonne
• Le mapping O/R est plus complique:
– Comment projeter l'héritage ?
– Comment projeter les relations entre objets ?
– Comment projeter les types de données Java ?
–…
Suite
• Il y a de nombreuses conceptions possibles…
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

8
API de persistance avec JDBC / DAO 1/2
• Les objets persistants sont des JavaBeans
• Vous y accédez via des DAO
– Data Access Object
• Implémente les méthodes de persistance:
– Insérer, détruire, modifier, requêtes…
PersonneDAO
Personne
prenom
nom
email

Thibault Cuvillier
Creative Commons 2.0

inserer
détruire
modifier
requete(prenom, nom)

javax.persistence / Introduction

9
API de persistance avec JDBC/DAO 2/2
• La couche de persistance prend en charge le
mapping O/R
– Hard-codé en Java, Séparé des données
Application

Persistance
POJO

Mapping O/R

• Mais:
– Un objet peut être chargé deux fois en mémoire
– La navigation entre objets est délicate à gérer
– Les objets ne sont stockés en cache, générant un flux
important de requêtes SQL
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

10
Cache de persistance
• L'ajout d'un cache permet:
– De limiter le nombre de requêtes SQL
– De ne conserver en mémoire qu'un seul exemplaire des
objets persistants

Application

Persistance
POJO

Cache

Mapping O/R

• Mais, comment gérer les transactions ?
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

11
Cache transactionnel
• Le cache doit être transactionnel
– Isolation transactionnelle
– Consistance
• Il doit être multi-thread safe
Persistance
POJO
Application

Cache

Mapping O/R

Gestion des transactions
Gestion de la sécurité

• Cette solution est complexe
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

12
Outils de mapping O/R
• Moteur de mapping générique
– utilise une description du mapping
• Cache transactionnel
• Les objets persistants sont
des POJOs
• Un DAO générique

mapping.xml
Description
du mapping O/R

Persistance
API
Application

Cache

Mapping O/R

Gestion des transactions
Gestion de la sécurité

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

13
Mapping objet relationnel
• Produits de mapping objet / relationnels
– Hibernate, JDO, Toplink (Oracle)
• Ces produits savent:
– Mapper une classe sur plusieurs tables,
– Mapper des objets dépendants,
– Mapper types complexes,
– Mapper des relations,
– Mapper l'héritage entre entités,
– Gérer des caches locaux ou distribués.
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

14
Exemple Hibernate 1/2
Client.hbm.xml
<hibernate-mapping>
<<Entity>>
Client
id
prénom
nom
téléphone

POJO

<class name="com.btc.Client" table="CLIENT">
<property name="prénom">
<column name="PRENOM" length="32"/>
</property>
…
</class>
</hibernate-mapping>

Mapping O/R

<<Tables>>
CLIENT
ID
PRENOM
NOM
TELEPHONE
RUE

1
Adresse
rue
ville
codePostal

<<Table>>
EMAIL

0..*
EMail
email

Thibault Cuvillier
Creative Commons 2.0

CLIENT_FK
EMAIL
javax.persistence / Introduction

VILLE
CODEPOSTAL

Tables
15
Exemple Hibernate 2/2
• Le code client devient simple et naturel:
Session session = … ouvrir la session Hibernate …;
Transaction tx = session.beginTransaction();
tx.begin();
Client client = new Client();
client.setPrénom("Bill");
client.setNom("Gates");
Adresse adresse = new Adresse("5 rue de l'église", "Lyon", "69002");
client.setAdresse(addresse);
client.addEMail("bill@microsoft.com");
client.addEMail("bilou@microsoft.com");
session.save(client);
tx.commit();
session.close();
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

16
javax.persistence
• Nouvelle API Java de persistance
– Implémentations avec Hibernate, JDO, Toplink ou autre
– J2EE (module EJB ou Web) ou J2SE
• package javax.persistence
PersistenceContext
– Fonctionne avec J2SE et J2EE
PersistenceContext
• Contexte de persistance:
– Gère le cache des objets
PersistenceContext
– Transactionnel
– Durée de vie: TRANSACTION ou EXTENDED
– Une application peut utiliser plusieurs contextes
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

17
Entités
• Interface unifiée
• Le descripteur de mapping O/R standard
– Peut être généré à partir d'annotations Java5.
@Entity
public class Client extends Serializable {
private long _id;
private String _nom;
@Id public long getId() { return _id; }
public void setId(long id) { _id = id; }
public String getNom() { return _nom; }
public void setNom(String nom) { _nom = nom; }
…
}

Cette entité est complète !

Mapping par défaut
<<Tables>>
CLIENT
ID
NOM

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

18
Cycle de vie des Entités
• Gérée = associée à un contexte de
persistance
Etat
Dans la base
Associé à un contexte
de persistance
Transitoire Non

Non

Existe

Oui

Oui

Détaché

Oui

Non

Détruit

Non

Oui

Non Géré
Transitoire

Détaché

Thibault Cuvillier
Creative Commons 2.0

Géré dans un contexte
persist
cascade
merge

Existe

find
query EJBQL

persist
Détruit

sérialisation
fin de TX
javax.persistence / Introduction

19
Avantages des Entités
• Objets persistants de faible granularité
– Plus proche du modèle d'analyse
• Mapping O/R puissant
• Fonctionne avec J2EE et J2SE
• Langage de Query: EJBQL
• Accès direct à la connexion sous jacente
– Pour optimisations
– Pour utiliser des API spécifiques (Hibernate, JDO)
• Permet de générer le schéma de la base à partir
des annotations (pas recommandé)
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

20
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

Mapping Objet / Relationnel
Niveau 1
JP 1.1 - Template 1.0
Mapping OR
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

22
Mapping O/R > Mapping simple
• Mapping O/R
Mapping simple
Identité simple
Callback

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

23
Classe persistante
• Doit être annotée avec @Entity
@Entity(name="Compte"
access=AccessType.PROPERTY)

– name
Nom de l'entité utilisé dans les expressions EJBQL
select c from Compte c where c.solde < 0
– access
Annotation des attributs persistants sur le getter
(PROPERTY, par défaut) ou sur les attributs (FIELD) qui
ne doivent pas être privés (à éviter!).
• Doit avoir un constructeur par défaut
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

24
Mapping 1 classe / 1 table 1/3
• Annotation @Table
– name : Nom de la table, nom de la classe.
– catalog : Catalogue de la table, celui de la ctx.
– schema: Schéma de la table, celui de la ctx.
• Pour générer le schéma:
– UniqueContraint uniqueContraints[]
Contraintes d'unicité simples ou composites
– Annotation @UniqueContraint
• columnNames: colonnes dans la contrainte

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

25
Mapping 1 classe / 1 table 2/3
• Table: <schéma par
défaut>.Client
• Table: <schéma par
défaut>.CLIENT_TBL

• Table: FORMATION.
CLIENT_TBL
Thibault Cuvillier
Creative Commons 2.0

@Entity
public class Client implements Serializable { … }

@Entity
@Table(name="CLIENT_TBL")
public class Client implements Serializable { … }

@Entity
@Table(name="CLIENT_TBL",
schema="FORMATION")
public class Client implements Serializable { … }
javax.persistence / Introduction

26
Mapping 1 classe / 1 table 3/3
• Table FORMATION.CLIENT_TBL + contrainte
d'unicité sur (prenom, nom) et (telephone)
@Entity
@Table(
name="CLIENT_TBL",
uniqueConstraints={
@UniqueConstraint(columnNames={"nom", "prenom"}),
@UniqueConstraint(columnNames={"telephone"})}
)
public class Client implements Serializable { … }
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

27
Propriétés persistantes 1/2
• Doit avoir un des types suivants:
– Type primaire Java: int, long, double …
– String, BigInteger, BigDecimal, Date, Calendar, Date…
– byte[], Byte[], char[], Character[]
– enums Java5 (colonne integer ou String)
– Classe Java sérializable (a éviter, voir + loin)
– Classe Java dépendante (voir + loin)
– Collection, Set, List, Map ou génériques List<T>…
• Type de base, Entités.
– Attention, les types de base ne peuvent être NULL
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

28
Propriétés persistantes 2/2
• Déclarez les accesseurs public:
– T getX() et void setX(T t)
– boolean isX() et void setX(boolean b)
• Peuvent ou non être déclarés dans l'interface
• Ne doivent pas exécuter de logique métier
• Si une exception est levée dans getX ou setX , la
transaction rollback.
private transient String _pwdDecrypté;

• Attributs non persistant:
Thibault Cuvillier
Creative Commons 2.0

@Transient
public String getPwdDecrypté() {…}
javax.persistence / Introduction

29
@Basic, @Temporal
• Indique un mapping simple pour une propriété
persistante
– Par défaut, toutes les propriétés sont persistantes
• @Basic
– fetch = EAGER ou LAZY
– optional =
@Basic
true ou false
@Temporal(TemporalType.DATE}
• @Temporal
public Date getDateNaissance() {
– value = TIMESTAMP , return _ddn;
DATE, TIME
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

30
Mapping 1 propriété / 1 colonne 1/3
• Utilisez l'annotation @Column
– name: Nom de la colonne - Nom de la propriété
– insertable : utilisée dans INSERT? - true
– updatable : utilisée dans UPDATE? - true
• Pour pouvoir générer le schéma:
– nullable : peut être NULL? - true
– unique : Valeur est unique dans la table - false
– columnDefinition - Définition SQL de la colonne
– length : longueur de la column - 255
– precision , scale pour les colonnes numérique - 0
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

31
Mapping 1 propriété / 1 colonne 1/3
• Colonne "NOM"
VARCHAR(255)

private String _nom;
public String getNom() { return _nom; }
public void setNom(String nom) { _nom = nom; }
private String _nom;

• Colonne "NAME"
VARCHAR(32)

@Column(name="NAME", length=32)
public String getNom() { return _nom; }
public void setNom(String nom) { _nom = nom; }
private String _nom;

• Colonne "NAME"
VARCHAR(32)
NOT NULL
Thibault Cuvillier
Creative Commons 2.0

@Column(name="NAME", length=32, nullable=false)
public String getNom() { return _nom; }
public void setNom(String nom) { _nom = nom; }
javax.persistence / Introduction

32
Mapping 1 propriété / 1 colonne 3/3
• Colonne "DESC"
CLOB

private String _desc;
@Column(columnDescription="CLOB")
public String getDesc() { return _desc; }
public void setDesc(String desc) { _desc = desc; }
private Time _time;

• Colonne "TIME"
TIMESTAMP

@Column(columnDescription="TIMESTAMP")
public Time getTime() { return _time; }
public void setTime(Time time) { _time = time; }

• Colonne "SOLDE"private double _solde;
Non modifiable @Column(precision=12, updatable="false")

public double getSolde() { return _solde; }
public void setSolde(double solde) { _solde = solde; }

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

33
Mapping O/R > Identité simple
• Mapping O/R
Mapping simple
Identité simple
Callback

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

34
Identité
• L'identité d'une Entité = Clef Primaire
• Identité métier:
– Identité simple = Une seule valeur
– Identité composite = Plusieurs valeurs
• Identité technique: une colonne neutre
– Entier long
– Séquence Oracle, Colonne automatique MySQL…
!

L'identité d'une entité doit être invariable .
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

35
Recommandations
• N'utilisez que des Identificateurs neutres
– Long ou long
– Initialisation: séquence, table de compteurs, colonnes à
incrémentation automatique…
• Ajoutez si nécessaire des colonnes pour améliorer
la performance des requêtes
<<Table>> Soctété

id
nom
prénom
téléphone
sociétéId

id
nom

Thibault Cuvillier
Creative Commons 2.0

<<Table>> Facture

<<Table>> Client

id
clientId
sociétéId
montantHT
montantTTC
tva
javax.persistence / Introduction

36
Identité simple 1/4
• La propriété contenant l'identité: @Id
• Pour une identité technique générée:
• @GeneratedValue
– strategy
NONE: pas de génération - Valeur par défaut
TABLE: utilisation d'une table pour gérer les ID
SEQUENCE: utilisation de séquences (Oracle par ex.)
IDENTITY: génération de la valeur par la base
AUTO: génération par le fournisseur de persistance
– String generator (Si generate != NONE)
Nom du générateur
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

37
Identité simple 2/4
• La valeur de l'ID
est contrôlée par
l'application

@Id
public long getId() { return _id; }

@Id

• La valeur de l'ID
est fixée lors
d'un INSERT par
une séquence.

@GeneratedValue(strategy=GenerationType.SEQUENC
E,
generator="CLIENT_ID_SEQ")
@SequenceGenerator(
name="CLIENT_ID_SEQ",
sequenceName="CLIENT_ID",
initialValue=0,
allocationSize=50)
public long getId() { return _id; }

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

38
Identité simple 3/4
• Les ID sont générés
à partir de la table
IDGEN possédant
une colonne
ID_KEY (PK),
ID_VAL.
• La valeur de l'ID
suivant utilise la
clef "CLIENT_ID".

@Id
@GeneratedValue(
strategy=GenerationType.TABLE,
generator="CLIENT_ID_TBL")
@TableGenerator(
name="CLIENT_ID_TBL",
table="IDGEN",
pkColumnName="ID_KEY",
valueColumnName="ID_VAL",
pkColumnValue="CLIENT_ID",
initialValue=1,
allocationSize=25)
public long getId() { return _id; }

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

39
Identité simple 4/4
• La valeur de l'ID est générée par la base, par
une colonne à incrémentation automatique
• Colonne Automatic MySQL, Identity HsQL
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public long getId() {
return _id;
}

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

40
Mapping O/R > Callbacks
• Mapping O/R
Mapping simple
Identité simple
Callback

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

41
Callbacks
• Méthodes déclenchées
pour notifier les
changements d'états
d'une entité

@Entity
public class Login {
private String password;
private String cryptedPassword;
@PrePersist
@PreUpdate
public void preUpdate() {
cryptedPassword = crypt(password);
}

}
Thibault Cuvillier
Creative Commons 2.0

@PostLoad
public void postLoad() {
password = decrypt(cryptedPassword);
}
…
javax.persistence / Introduction

42
Callbacks des entités
• @PrePersist et @PostPersist
– Appelé avant et après EntityManager.persist()
• @PreRemove et @PostRemove
– Appelé avant et après EntityManager.remove()
• @PreUpdate et @PostUpdate
– Appelé avant et après une maj dans la base
• @PostLoad
– Appelé après le chargement de l'entité

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

43
Listener d'entité
• Vous pouvez mettre le code des callbacks dans
un listener avec @EntityListener.
Personne.java
@Entity
@EntityListener(com.btc.LogListener)
public class Personne { …}

!

Les listeners sont
hérités !

LogListener.java
public class LogListener {
L'entité est passée en
@PrePersist
! paramètre
public void prePersist(Object o) {
System.out.println("PrePersit(o=" + o+")");
}
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

44
Travaux pratiques
• Ouvrez le projet JP-Lab01-Mapping-Question
– Suivez les instructions

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

45
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

EntityManager

JP 1.1 - Template 1.0
EntityManager
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

47
EntityManager
• Permet de changer l'état persistant des entités
– Création, destruction, modification
• Associé à un contexte de persistance
• Permet d'exécuter des requêtes
– EJBQL: select c from client c where c.nom=:nom
– Permet de fermer le contexte de persistance (J2SE)
– Permet de contrôler les transactions (J2SE ou pas JTA)

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

48
Création d'un EntityManager avec J2SE
Attention, différent pour
• L'EntityManager est créé par une
un serveur J2EE
factory
• La factory contient la description du mapping

EntityManagerFactory factory = Persistence.createEntityManagerFactory(
"em", new Properties());
EntityManager em = factory.createEntityManager();

• Vous pouvez utiliser plusieurs contextes de
persistance dans votre application
– Une factory par contexte de persistence
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

49
persistence.xml
• La factory est décrite dans le fichier
Transactions:
META-INF/persistence.xml
•RESOURCE_LOCAL
•JTA

<?xml version="1.0" encoding="UTF-8"?>
<persistence>
<persistence-unit name="em" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="root"/>
<property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1/db"/>
</properties>
</persistence-unit>
Attention avec un serveur J2EE,
</persistence>

utilisation de JNDI et de JTA

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

50
TRANSACTION et EXTENDED 1/2
• Le contexte de persistance maintient les données
en cache.
• Le cache peut avoir deux durées de vie:
– TRANSACTION
Les caches sont vidés à la fin de chaque transaction
– EXTENDED
Les caches sont vidés lorsque le contexte est fermé
• Le cache peut être paramétré
– Annotations et paramétrage XML non standard
– Dépend de l'implémentation
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

51
TRANSACTION et EXTENDED 2/2
• Pour créer un EntityManager EXTENDED:
EntityManagerFactory factory = Persistence.createEntityManagerFactory(
"em", new Properties());
EntityManager em = _factory.createEntityManager(
PersistenceContextType.EXTENDED );
…
em.close();

• Il est préférable d'utiliser des caches
transactionnels et de reposer ainsi sur l'isolation
transactionnelle de la base
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

52
EntityManager.find
• EntityManager.find(Class c, Object id)

– Charge un objet en mémoire et le retourne
• EntityManager.getReference(Class c, Object id)

– Ne charge pas l'objet en mémoire, ne contient que l'ID.
– L'état sera chargé lors du premier accès à une propriété
persistante
EntityManager em = … on verra plus loin …;
Client client = em.getReference(Client.class, "Bill Gates");
em.remove(client);

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

53
Gérer les transactions
EntityManager em = …;
• Pas de transactions
EntityTransaction tx =
imbriquées
em.getTransaction();
• S'il n'y a pas de transaction, tx.begin();
le contexte de persistance, try {
… modifier les données …
la méthode find:
tx.commit();
– en commence une
} catch(Exception e) {
tx.rollback();
– la termine à la fin de la
throw e;
méthode
}
– retourne une entité détachée
• Pour modifier les données dans la base, il
suffit de modifier un objet géré
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

54
EntityManager.persist 1/2
• void persist(Object entity)
Etat

Action

Transitoire Insertion dans la base (1)
Géré

Rien sur l'entité(1)

Détaché

IllegalArgumentException

Détruit

L'entité redevient managée (1)

– (1) Cascade sur les entités référencées si
cascade=PERSIST ou ALL
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

55
EntityManager.persist 2/2
• Exemple:
EntityManager em = …;
EntityTransaction tx = em.getTransaction();
tx.begin();
Client client = new Client();
client.setPrénom("Harry");
client.setNom("Cover");
client.setTéléphone("0404040404");
em.persist(client);
tx.commit();
System.out.println("Client id = " + client.getId());
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

56
EntityManager.remove
• void remove(Object entity)
Etat

Action

Transitoire

Rien sur l'entité, mais cascade (1)

Géré

Destruction de l'entité et cascade (1)

Détaché

IllegalArgumentException

Détruit

Rien

– (1) Cascade sur les entités référencées si
cascade=REMOVE ou ALL
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

57
EntityManager.merge
• <T> T merge(T entity)
– Retourne une nouvel
entité géré

!

Attention, avec Hibernate,
provoque une lecture de l'objet
pour comparer son état.

Etat
Transitoire
Géré

Action
Création de l'entité (1)
Rien sur l'entité (1)

Détaché

Copie de l'état dans une entité gérée avec la
même identité (1)
IllegalArgumentException

Détruit

– (1) Cascade sur les entités référencées si
cascade=MERGE ou ALL javax.persistence / Introduction
Thibault Cuvillier
Creative Commons 2.0

58
EntityManager.merge: exemple
• La méthode fetch retourne l'objet persistant et le rend
détache du contexte de persistance.
• La méthode save met à jour l'objet dans le contexte de
persistance.
• fetch et save sont des méthodes transactionnelles
public Client fetchClient(long idclient) {
EntityManager em = …;
return em.find(Client.class, idclient);
}

Ne pas utiliser getReference:
pourquoi ?

public void saveClient(Client client) {
EntityManager em = …;
em.merge(client);
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

59
Objets détachés
• Un objet persistant devient détaché quand:
– Le contexte de persistance se termine:
• TRANSACTION: Fin de la transaction
• EXTENDED: Fermeture explicite du contexte
– Quand l'objet est sérialisé
• Passage par valeur pour les interfaces Remote
– Quand l'objet est cloné
EJB Session
EntityManager
Navigateur
Web
GET EditClient.jsp
Client c = fetchClient("Bill Gates")
find
SELECT
POST EditClient.jsp
saveClient(c)
merge
UPDATE
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

Base

60
Transactions optimistes 1/2
• Un objet peut être modifié entre sa lecture et son
merge par une autre requête
– La dernière écriture gagne
• Transaction longue
– Gestion pessimiste: vous devez gérer le verrouillage
– Gestion optimiste: vous ajoutez une propriété Version
• La version est incrémentée à chaque modification
– Lors du merge, le contexte de persistance vérifie si le
numéro de version a changé.
– Exception dans ce cas, et rollback de la transaction
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

61
Transactions optimistes 2/2
• Il faut identifier la propriété contenant le numéro
de version avec @Version
– Peut être du type: int, Integer, long, Long, short, Short,
Timestamp
public Person {
private long _version;
@Version
public long getVersion() {
return _version;
}
}

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

62
Mise à jour de la base de données
• La base de donnée est mise à jour lors du commit
ou avant l'exécution d'une query
• Pour forcer la mise à jour:
– EntityManager.flush()
– Exécute le SQL
• Vous pouvez recharger l'état d'un objet modifié à
partir de la base:
– EntityManager.refresh(Objet o)
– Annule les modifications apportées

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

63
Travaux pratiques
• Ouvrez le projet JP-Lab02-EntityManagerQuestion
– Suivez les instructions

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

64
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

EJBQL
Niveau 1
JP 1.1 - Template 1.0
EJBQL
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

66
Queries EJBQL simples
• EJBQL permet d'exécuter des requêtes
– Pour lire des données
– De faire des UPDATE et DELETE en masse
• Utilise le nom des entités et des propriétés
– Pas le nom des tables et colonnes
– Attribut name de l'annotation @Entity
– Abstract Schema Name
select c from Client c where c.name="Alonso Bistrot"

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

67
La clause SELECT
• SELECT c from Client c
– Retourne tous les clients
• SELECT c.name, c.email from Client c
– Retourne le noms et l'email de tous les clients
• SELECT COUNT(c) from Client c
– Retourne le nombre de clients
• SELECT AVG(c.age) from Client c
– Retourne l'age moyen des clients
– Autres fonctions: SUM, MIN, MAX
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

68
DISTINCT, ORDER BY, NEW
• Select DISTINCT c.name from Client c
– Retourne une liste de nom unique
• Select c from Client c order by c.name ASC
– Retourne la liste des clients triés par ordre alpha.
– Ascendant: ASC (par défaut), Descendant: DESC
• Permet de retourner une liste d'objets Java
quelconque
– Pas forcément des entités
select new com.btc.EmployeInfo(e.id, e.status, e.salaire) from Employe e

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

69
Opérateurs de la clause WHERE 1/2
• [NOT] BETWEEN
– WHERE c.age BETWEEN 0 and 17
– Equivalent à: c.age >= 0 AND c.age <= 17
• [NOT] LIKE
– select c from Client c where c.name LIKE 'B%'
– select c from Client c where c.name LIKE 'B_ _ _'
• [NOT] IN
– select c from Commande c where c.status IN('E', 'A', 'B')
• IS [NOT] NULL
– select c from Client c where c.status IS NULL
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

70
Fonctions EJBQL
• CONCAT("a", "b") => "ab"
• TRIM([BOTH, " ", ]" a ") => "a"

– 1er argument: BOTH, LEADING, TRAILING
•
•
•
•
•
•
•
•
•

LOWER("A") => "a"
UPPER("a") => "A"
LOCATE("ababab", "b" [, 3]) => 4
LENGTH("abcd") => 4
SUBSTRING("abcde", 2, 3) => "bcd"
ABS(-2) => 2
SQRT(4) => 2
MOD(101, 10) => 1
SIZE(c.commandes)
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

71
Opérateurs de la clause WHERE 3
• EXISTS
– Vrai si la sous-requête retourne au moins un objet
SELECT DISTINCT emp FROM Employee emp WHERE
EXISTS (
SELECT spouseEmp FROM Employee spouseEmp
WHERE spouseEmp = emp.spouse)

• ALL, ANY (ou SOME)
– ALL: Vrai si toutes les valeurs remplissent la condition
– ANY: Vrai si une valeur au moins remplie la condition
SELECT emp FROM Employee emp WHERE emp.salary > ALL (
SELECT m.salary FROM Manager m
WHERE m.department = emp.department)
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

72
GROUP BY
• GROUP BY permet de regrouper
les valeurs retournées par
la requête
• Requête sans clause GROUP BY:

Entreprise
SUN

Montant
5500

IBM
SUN

4500
7100

Entreprise

Montant

SUN

17100

IBM

17100

SUN

17100

Entreprise

Montant

IBM

4500

SUN

12600

select v.entreprise, SUM(v.montant)
from Vente v

• Requête avec la clause GROUP BY:
select v.entreprise, SUM(v.montant)
from Vente v group by c.entreprise
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

73
HAVING
• Permet de tester des valeurs agrégées
– Impossible dans une clause WHERE
select v.entreprise, SUM(v.montant)
from Vente v
group by v.entreprise
having sum(v.montant) > 10000

Thibault Cuvillier
Creative Commons 2.0

Entreprise

Montant

SUN

12600

javax.persistence / Introduction

74
DELETE et UPDATE
• Permet de déclencher des delete et update de
masse dans un batch.
• DELETE:
• UPDATE:

delete from Client c where c.status = 0
update Employe c set c.salary = 1500 where c.salary < 1500

• Le contexte de persistance n'est pas mis à jour
• Utiliser:
– Dans une transaction séparée
– Au début d'une nouvelle transaction
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

75
Exécuter une requête simples
• Les requêtes simples
public List findClients(EntityManager em) {
Query query = em.createQuery ("select c from Client c");
return query.getResultList ();
}

• Avec des paramètres
public List findClientsParStatus(EntityManager em, int status) {
Query query = em.createQuery("select c from Client c where c.status = :status");
query.setParameter("status", status);
return query.getResultList();
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

76
Requêtes nommées
• Déclarer les requêtes dans une annotation
@NamedQueries(
@NamedQuery(
name="getByName",
query="select e from Entreprise where name=:name"),
@NamedQuery(name="getAll", query="select e from Entreprise")
)
public class EntrepriseMgr {
public List<Entreprise> getEntreprises() {
Query query = _em.createNamedQuery("getAll");
return query.getResultList();
}
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

77
Utiliser le SQL natif
• Vous pouvez utiliser des requêtes SQL
public List getClients() {
Query query = _em.createNativeQuery ("select * from client", Client.class);
return query.getResultList();
}

• Vous pouvez utiliser @NamedNativeQuery

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

78
Mapping d'un ResultSet
• Vous pouvez mapper chaque colonne sur une ou
plusieurs classes
– Pas forcément des entités
@SqlResultSetMapping(
name="getClientsSummariesResults ",
entities=@EntityResult(entityClass=com.valtech.ClientSummary, fields={
FieldResult(name="id" column="client_id"),
FieldResult(name="name" column="client_name") })
)
public List getClientSummaries() {
return _em.createNativeQuery(
"select c.id as client_id, c.name as client_name from client c",
" getClientsSummariesResults "). getResultList();
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

79
Travaux pratiques
• Ouvrez le projet JP-Lab03-EJBQL-Question
– Suivez les instructions

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

80
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

Mapping O/R
Niveau 2
JP 1.1 - Template 1.0
Mapping avancé
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

82
Mapping des relations
Mapping avancé
Mapping des relations
Mapping de l'héritage
Autres mappings

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

83
Relations entre Entités
• Support des relations 1-1, 1-n, n-m
• Les relations peuvent uni ou bidirectionnelles
• Certaines opérations peuvent se propager au
travers des relations
– Cascade: remove, persist, merge …
remove
– Que sur les relations
OneToOne ou OneToMany
Commande
remove
Ligne1

Thibault Cuvillier
Creative Commons 2.0

remove
Ligne2

javax.persistence / Introduction

remove
Ligne3

84
Relation 1-1
Map sur la table PERSONNE
Propriétaire de la relation
@Entity
public class Personne {
private long _id;
private Login _login;
@OneToOne
public Login getLogin() {
return _login;
}
public void setLogin(Login login) {
_login = login;
}

Map sur la
colonne ID

Map sur la table LOGIN

@Entity
public class Login {
private Personne _personne;
private String _login;
private Stirng _password;

@OneToOne(mappedBy="login")
public Personne getPersonne() {
return _personne;
}
public void setPersonne(Personne p) {
_personne = p;
}

}
PERSONNE contient une FK sur LOGIN
colonne = <Propriété>_<column PK> = LOGIN_ID
Thibault Cuvillier
Creative Commons 2.0

Optionnel si la
relation est
unidirectionnelle

}
javax.persistence / Introduction

85
Annotation OneToOne
• @OneToOne
– (O) String mappedBy = ""
Propriété propriétaire de la relation
– (O) boolean optional = true
Peut ou non être null
– (O) targetEntity = type de la propriété
Le type de l'entité référencée
– (O) CascadeType [] cascade = {}
Opérations à cascader au travers de la relation: ALL, PERSIST,
REMOVE, REFRESH
– (O) fetchType fetch = EAGER
Accès aux entités en mode LAZY ou EAGER
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

86
Fetch des entités
• EAGER:
– Les objets liés sont chargés en une seule requête SQL
1 find(Personne.class, id)
2 getLogin()

EntityManager
Personne

Login

• LAZY:
– Chargement de l'identité
– Chargement de l'état lors du premier accès
1 find(Personne.class, id)
2 getLogin()

Thibault Cuvillier
Creative Commons 2.0

EntityManager
Personne

javax.persistence / Introduction

Login
87
Relation 1-n
Map sur la table LOGIN
Propriétaire de la relation

@Entity
public class Login {
private long _id;
private Role _role;

Map sur la
colonne ID

Map sur la table ROLE

@Entity
public class Role {
private long _id;
private List<Login> _logins;

@ManyToOne
public Role getRole() {
return _role;
}
public void setRole(Role r) {
_role = r;
}

Optionnel si la
relation est
unidirectionnelle

@OneToMany(mappedBy="role")
public List<Login> getLogins() {
return _logins;
}
public void setLogins(List<logins> l) {
_logins = l;
}

}
}
LOGIN contient une FK sur ROLE
colonne = <Propriété>_<column PK> = ROLE_ID
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

88
Intégrité des relations
• C'est au développeur d'assurer l'intégrité des
relations
– Positionner la relation inverse Login login = new Login();
Person person = new Person();
– Lors du chargement, le lien
inverse est positionné
login.setPerson(person);
automatiquement
person.setLogin(login);
• Une relation est mise à jour dans la base à partir
de son propriétaire

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

89
Annotations ManyToOne et OneToMany
• ManyToOne: même attributs que OneToOne
• OneToMany: même attributs que OneToOne
– Sauf fetch qui vaut LAZY
• Avec les collections génériques:
@OneToMany(mappedBy="role")
List<Personne> getPersonnes() {…}

• Avec les collections non génériques:
@OneToMany(targetEntity=Personne.class, mappedBy="role")
List getPersonnes() {…}

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

90
Relation n-m
Map sur la table ROLE
Propriétaire de la relation

@Entity
public class Role {
private long _id;
private List<Authorization> _authorizations;
@ManyToMany
public List<Authorization> getAuthorizations() {
return _authorizations;
}
public void setAuthorization(List<Authorization> a) {
_authorizations = a;
}
}

Map sur la table
AUTHORIZATION

Map sur la
colonne ID
@Entity
public class Authorization {
private long _id;
private List<Role> _roles;

Optionnel si la
relation est
unidirectionnelle

@ManyToMany(mappedBy="authorizations")
public List<Role> getRoles() {
return _roles;
}
public void setRoles(List<Role> r) {
_roles = r;
}

Table d'association: ROLE_AUTORIZATIONS
PK: ROLE_ID
PK: AUTHORIZATIONS_ID
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

91
Mapping d'une clé étrangère 1/2
Jointure
composite
Jointure
simple

@Entity
public class Login {
private long _id;
private Role _role;
@ManyToOne
@JoinColumn(
name="ROLE_FK")
public Role getRole() {
return _role;
}
}
Thibault Cuvillier
Creative Commons 2.0

@Entity
public class Entreprise {
private long _id;
private Personne _pdg;
@ManyToOne
@JoinColumns( {
@JoinColumn(name="PDG_FIRST_NAME_PK",
referencedColumnName="FIRST_NAME"),
@JoinColumn(name="PDG_LAST_NAME_PK")
referencedColumnName="FIRST_NAME"),
})
public Personne getPDG() {
return _pdg;
}
}
92
javax.persistence / Introduction
Mapping d'une clé étrangère 2/2
• @JoinColumn
– (O) String name
Nom de la colonne contenant la clef étrangère.
Par défaut: <Propriété du référant>_<PK du référé>
– (O) String referencedColumnName
Clef primaire dans la table du référencé
– (O) boolean unique = false
– (O) boolean nullable = true
– (O) insertable = true
– (O) updatable = true
– (O) columnDefinition
– (O) secondaryTable (on verra plus loin)
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

93
Mapping d'une table d'association
• @JoinTable permet de préciser le nom de la table
d'association
@ManyToOne
@JoinTable(
name="ENTREPRISE_PDG",
joinColumns = @JoinColumn(name="PDG_FK",
referencedColumnName="ID"),
inverseJoinColumns = @JoinColumn(name="ENT_FK",
referencedColumnName="ID")
)
public Personne getPDG() {
return _pdg;
}
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

94
Mapper une HashMap
• Permet de mapper la valeur des clefs d'une Map
– @MapKey: name contient le nom de la propriété
persistante qui formera la clef
– Par défaut: la clef primaire
@OneToMany
@MapKey(name="id")
public Map<PersonneID, Personne> getEmployés() {
return _employés;
}

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

95
Ordre des relations
• Permet d'ordonner les
objets liés en fonction
d'un ou plusieurs
propriétés.
• @OrderBy
– Par défaut: la PK ASC

@Entity
public class Role {
@Id long _id;
private List<Login> _logins;
@OneToMany(mappedBy="role")
@OrderBy("user ASC")
public List<Login> getLogins() {
return _logins;
}
public void setLogins(List<logins> l) {
_logins = l;
}
}

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

96
BLOB et CLOB
• Permet de préciser le type d'une colonne
contenant un Large OBject
@Entity
– Propriété String
public class Role {
CLOB: données texte
private JPEGImage _image;
– Autre type de donnée
@Lob
BLOB: données binaires
• fetch: EAGER ou
@Basic(fetch=FetchType.LAZY)
public JPEGImage getPhoto() {
LAZY
return _image;

}
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

97
Travaux pratiques
• Ouvrez le projet JP-Lab04-Relation-Question
– Suivez les instructions

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

98
Mapping de l'héritage
Mapping avancé
Mapping des relations
Mapping de l'héritage
Autres mappings

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

99
Héritage
• Une entité peut hériter d'une autre entité
– Héritage des propriétés
– Héritage des relations
– Requêtes EJBQL polymorphes
• Une entité peut être abstraite
– Jamais instanciée
– Possède un mapping O/R
– Peut faire la cible de requêtes polymorphes
• Une entité peut hériter d'une classe Java qui n'est
pas une entité
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

100
Une table par hiérarchie
• Une colonne donne le
type de l'objet:
– Le discriminant
• Requête polymorphe:
– select v from Voiture v
where v.couleur ='rouge'

Voiture
id
couleur

0..n

1

Berline
barresDeToit

Attention, toutes les
propriétés doivent être
nullable.

Personne

Cabriolet
toit=capote, hardtop

VOITURE
disc

Thibault Cuvillier
Creative Commons 2.0

propriétaire

id

couleur

proprietaire

javax.persistence / Introduction

barresDeToit

toit
101
Une table par hiérarchie: exemple
@Entity
@Inheritance(
strategy=SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType=STRING
)
public abstract class Voiture {
@Id long _id;
private Personne _propriétaire;
STRING, CHAR,
private String _couleur;
INTEGER
…
}

• Chaque sous
classe doit
utiliser une
valeur différente
du discriminateur

@Entity
@DiscriminatorValue("B")
public class Berline extends Voiture {
private boolean barresDeToit;

@Entity
@DiscriminatorValue("C")
public class Cabriolet extends Voiture {
public enum Toit {HARDTOP, CAPOTE};
private Toit _toit;

}

}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

102
Une table par classe concrète
• Consomme peu de place
disque
• Requêtes polymorphes
coûteuses

Voiture
id
couleur

propriétaire
0..n

1

Berline

Personne

Cabriolet

barresDeToit

toit=capote, hardtop

Le support de ce
mapping est optionnel

CABRIOLET

BERLINE
id

couleur

proprietaire

Thibault Cuvillier
Creative Commons 2.0

barresDeToit

id

couleur

javax.persistence / Introduction

proprietaire

toit
103
Une table par classe concrète: exemple
@Entity
@Inheritance(strategy=TABLE_PER_CLASS)
public abstract class Voiture {
@Id long _id;
private Personne _propriétaire;
private String
_couleur;
…
}
@Entity
public class Berline extends
Voiture {
private boolean barresDeToit;

@Entity
public class Cabriolet extends Voiture {
public enum Toit {HARDTOP, CAPOTE};
private Toit _toit;

}

}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

104
Une table par classe
• Proche du modèle objet
• Performance des
requêtes

Voiture
id
couleur

propriétaire
0..n

Personne

1

Berline

Cabriolet

barresDeToit

toit=capote, hardtop

VOITURE
id

couleur

proprietaire

BERLINE
id
Thibault Cuvillier
Creative Commons 2.0

barresDeToit
javax.persistence / Introduction

CABRIOLET
id

toit
105
Une table par classe: exemple
@Entity
@Inheritance(strategy=JOINED
)
public abstract class Voiture {
@Id long _id;
private Personne _propriétaire;
private String
_couleur;
…
}
@Entity
public class Berline extends
Voiture {
private boolean barresDeToit;
}

• Les sous classes
contiennent une FK sur
la classe de base
• Peut être renommée
avec
@PrimaryKeyJoinColum
n
@Entity
public class Cabriolet extends Voiture {
public enum Toit {HARDTOP,
CAPOTE};
private Toit _toit;
}

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

106
Travaux pratiques
• Ouvrez le projet JP-Lab05-Inheritance-Question
– Suivez les instructions

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

107
Autres mappings
Mapping avancé
Mapping des relations
Mapping de l'héritage
Autres mappings

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

108
Les classes embedded
• Classe Java contenant une partie de l'état de
l'entité
@Embeddable
public class Adresse {
– Toujours un lien 1:1
@Entity
Personne
public class Personne {
private Adresse _adresse;

Adresse

Colonnes de la table
PERSONNE

private String _rue;
private String _ville;
…

}
@Embedded
@AttributeOverrides( {
@AttributeOverride(name="rue", column=@Column(name="street")),
@AttributeOverride(name="ville", column=@Column(name="city"))
})
public Adresse getAdresse() { return _adresse; }
public void setAdresse(Adresse adresse) { _adresse = adresse; }
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

109
Super classe mappées
• Factorise des mapping communs entre classes
• Pas d'annotation pour
contrôler l'héritage
– La super-classe est intégrée @MappedSuperclass
public class Personne {
dans la définition de
private String _prénom;
private String _nom;
la sous classe
@Entity
@AttributeOverride(
name="NomDeFamille",
column = @Column(name="NOM2FAMILLE"))
public class Employe extends Personne {
private String _matricule;
public String getMatricule() {…}
}
Thibault Cuvillier
Creative Commons 2.0

public String getPrenom() {…}
@Column(name="NOM")
public String getNomDeFamille() {…}
}

javax.persistence / Introduction

110
Identité composite 1/2
• L'identité d'une Entité peut être encapsulé dans
une classe
– Bonne pratique: pourquoi ?
• Deux solutions:
@Embeddable
public class PersonneID {
private String _nom;
@Entity
public class Personne {
L'identificateur mapprivate Date _ddn;
sur une propriété …
private PersonneID _id;
public int hashCode() {…}
public boolean equals(Object o) {…}
@EmbeddedId
}
public PersonneID getID() { return _id; }
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

111
Identité composite 2/2
• Chaque propriété de l'identificateur map sur une
propriété de l'entité
@Entity
@IdClass(ClientID.class)
public class Client {
private String _nom;
private String _prenom;

public class ClientID
implements Serializable {
private String _nom;
private String _prenom;
public ClientID() {}
public getNom() {…}
…
public long hashcode() { … }
public boolean equals(Object o) {
…
}

public String getNom() {
return _nom;
}
…
}
}
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

112
Mapper une classe sur plusieurs tables
@Entity
@Table(name="PERSONNE")
@SecondaryTable(
name="PERSONNE_DETAILS",
pkJoinColumn=@PrimaryKeyJoinColumn(
name="PERSONNE_FK"))
public class Personne {
private long _id;
private String _prénom;
private String _nom;
private String _couleurYeux;
private String _couleurCheuveux;
@Column(
name="COULEUR_YEUX",
table="PERSONNE_DETAILS)
public String getCouleurYeux() {…}
public String getCouleurCheuveux() {…}
}

Thibault Cuvillier
Creative Commons 2.0

• L'entité est répartie sur
plusieurs tables
• Plus d'une table
secondaire:
– @SecondaryTables
PERSONNE
id

PRENOM

…

PERSONNE_DETAILS
PERSONNE_FK

COULEUR_YEUX

javax.persistence / Introduction

…

113
Travaux pratiques
• Ouvrez le projet JP-Lab06-Embedded-Question
– Suivez les instructions

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

114
Author: Thibault Cuvillier – Creative Commons 2.0

javax.persistence

EJBQL
Niveau 2
JP 1.1 - Template 1.0
EJBQL avancé
Introduction à javax.persistance
Mapping
EntityManager
EJBQL
Mapping avancé
EJBQL avancé

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

116
Opérateurs sur les relations
• IN(<Relation ToMany>)
– Jointure entre deux entités
– select c from Commande c, IN(c.lignes) l
WHERE l.produit = 'Imprimante'
• IS [NOT] EMPTY
– select c from Commande c where c.lignes IS EMPTY
• [NOT] MEMBER OF
– Tester si une entité est ou non membre d'une relation

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

117
Les jointures SQL
• Un JOIN permet de combiner les lignes de
plusieurs tables
• Deux types de jointures EJBQL:
– [INNER] JOIN
– LEFT [OUTER] JOIN
• Prenons un exemple:
id
1
2
3

Client
nom
John Doeuf
Alain Disoir
Sophie Fonfec

Thibault Cuvillier
Creative Commons 2.0

id
10
11
12
13

Commande
client
nom
1
Imprimante
2
Souris
2
Ecran
null
Clé USB

javax.persistence / Introduction

118
INNER Join
• Ne retourne pas les valeurs nulles de l'entité
jointe
– Il n'y a pas Sophie Fonfec dans le résultat !
• select c.nom, p.nom
from Client c INNER JOIN c.produits p
c.nom
p.nom
John Doeuf
Alain Disoir
Alain Disoir

Imprimante
Souris
Ecran

• Equivalent:
– select c.nom, p.nom from Client JOIN c.produits p
– select c.nom, p.nom from Client IN(c.produits) p
javax.persistence / Introduction
Thibault Cuvillier
Creative Commons 2.0

119
LEFT OUTER JOIN
• Retourne aussi les valeurs null de l'entité jointe
• select c.nom, p.nom
from Client c LEFT OUTER JOIN c.produits p
c.nom
John Doeuf
Alain Disoir
Alain Disoir
Sophie Fonfec

p.nom
Imprimante
Souris
Ecran
null

• Equivalent:
– select c.nom,p.nom from Client c LEFT JOIN c.produits
p
Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

120
FETCH
• select p from Produit p JOIN p.client c
– Lit les clients et produits en trois requêtes
select p from Produit p JOIN p.client c
load com.btc.join.Client
load com.btc.join.Client

Produit
Imprimante
Souris
Ecran

• select p from Produit p JOIN FETCH p.client c
– Lit les clients et produits en une seule requête
select p from Produit p JOIN p.client c

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

121
Sous-requêtes EJBQL
• Une requête peut contenir une sous-requête
SELECT c FROM Customer c WHERE (
SELECT COUNT(o) FROM c.orders o
) > 10

SELECT goodCustomer FROM Customer goodCustomer
WHERE goodCustomer.balance > (
SELECT avg(c.balance) FROM Customer c
)

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

122
Travaux pratiques
• Ouvrez le projet JP-Lab07-EJBQL2-Question
– Suivez les instructions

Thibault Cuvillier
Creative Commons 2.0

javax.persistence / Introduction

123

Contenu connexe

Tendances

JDBC: Gestion des bases de données en Java
JDBC: Gestion des bases de données en Java JDBC: Gestion des bases de données en Java
JDBC: Gestion des bases de données en Java Youness Boukouchi
 
JNDI Java Naming Derectory Interfaces
JNDI Java Naming Derectory InterfacesJNDI Java Naming Derectory Interfaces
JNDI Java Naming Derectory Interfacesbenouini rachid
 
Formation JAVA/J2EE
Formation JAVA/J2EEFormation JAVA/J2EE
Formation JAVA/J2EEInes Ouaz
 
Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications JavaAntoine Rey
 
Presentation hibernate nfe103
Presentation hibernate nfe103Presentation hibernate nfe103
Presentation hibernate nfe103MRamo2s
 
Introduction à Hibernate p.1
Introduction à Hibernate p.1Introduction à Hibernate p.1
Introduction à Hibernate p.1ATHMAN HAJ-HAMOU
 
Marzouk une introduction à jdbc
Marzouk une introduction à jdbcMarzouk une introduction à jdbc
Marzouk une introduction à jdbcabderrahim marzouk
 
Accès aux bases de données via jdbc
Accès aux bases de données via jdbcAccès aux bases de données via jdbc
Accès aux bases de données via jdbcRachid Lajouad
 
CDI mis en pratique avec Seam Social et Weld OSGI
CDI mis en pratique avec Seam Social et Weld OSGICDI mis en pratique avec Seam Social et Weld OSGI
CDI mis en pratique avec Seam Social et Weld OSGIAntoine Sabot-Durand
 
La persistance des données : ORM et hibernate
La persistance des données : ORM et hibernateLa persistance des données : ORM et hibernate
La persistance des données : ORM et hibernateYouness Boukouchi
 

Tendances (20)

4 Hibernate
4 Hibernate4 Hibernate
4 Hibernate
 
Springioc
SpringiocSpringioc
Springioc
 
JDBC: Gestion des bases de données en Java
JDBC: Gestion des bases de données en Java JDBC: Gestion des bases de données en Java
JDBC: Gestion des bases de données en Java
 
JNDI Java Naming Derectory Interfaces
JNDI Java Naming Derectory InterfacesJNDI Java Naming Derectory Interfaces
JNDI Java Naming Derectory Interfaces
 
Jdbc
JdbcJdbc
Jdbc
 
Formation JAVA/J2EE
Formation JAVA/J2EEFormation JAVA/J2EE
Formation JAVA/J2EE
 
Hibernate et jsf
Hibernate et jsfHibernate et jsf
Hibernate et jsf
 
Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications Java
 
Presentation hibernate nfe103
Presentation hibernate nfe103Presentation hibernate nfe103
Presentation hibernate nfe103
 
Introduction à Hibernate p.1
Introduction à Hibernate p.1Introduction à Hibernate p.1
Introduction à Hibernate p.1
 
Devoxx 15
Devoxx 15 Devoxx 15
Devoxx 15
 
JAVA, JDBC et liaison base de données
JAVA, JDBC et liaison base de donnéesJAVA, JDBC et liaison base de données
JAVA, JDBC et liaison base de données
 
Marzouk une introduction à jdbc
Marzouk une introduction à jdbcMarzouk une introduction à jdbc
Marzouk une introduction à jdbc
 
Accès aux bases de données via jdbc
Accès aux bases de données via jdbcAccès aux bases de données via jdbc
Accès aux bases de données via jdbc
 
Rapport tp1 j2ee
Rapport tp1 j2eeRapport tp1 j2ee
Rapport tp1 j2ee
 
Ejb 3
Ejb 3Ejb 3
Ejb 3
 
CDI mis en pratique avec Seam Social et Weld OSGI
CDI mis en pratique avec Seam Social et Weld OSGICDI mis en pratique avec Seam Social et Weld OSGI
CDI mis en pratique avec Seam Social et Weld OSGI
 
La persistance des données : ORM et hibernate
La persistance des données : ORM et hibernateLa persistance des données : ORM et hibernate
La persistance des données : ORM et hibernate
 
575
575575
575
 
Jdbc
JdbcJdbc
Jdbc
 

En vedette

RgaSAT: Fiscalização de Serviços via Rastreio GPS Autônomo
RgaSAT: Fiscalização de Serviços via Rastreio GPS AutônomoRgaSAT: Fiscalização de Serviços via Rastreio GPS Autônomo
RgaSAT: Fiscalização de Serviços via Rastreio GPS AutônomoLuiz Domingues
 
Estudo 4square sp rj (1)
Estudo 4square   sp rj (1)Estudo 4square   sp rj (1)
Estudo 4square sp rj (1)Elife Brasil
 
Checkins em Shopping Centers Brasil Pré e pós Natal
Checkins em Shopping Centers Brasil Pré e pós NatalCheckins em Shopping Centers Brasil Pré e pós Natal
Checkins em Shopping Centers Brasil Pré e pós NatalElife Brasil
 
QRGeoLocation - um padrão de entrada de dados em sistemas GPS
QRGeoLocation - um padrão de entrada de dados em sistemas GPSQRGeoLocation - um padrão de entrada de dados em sistemas GPS
QRGeoLocation - um padrão de entrada de dados em sistemas GPSAdriano Souza
 
Localizando o Foursquare nas Mídias Sociais
Localizando o Foursquare nas Mídias SociaisLocalizando o Foursquare nas Mídias Sociais
Localizando o Foursquare nas Mídias SociaisGilberto Rodrigues
 
Notice GPS Globe 850 globe4x4
Notice GPS Globe 850 globe4x4Notice GPS Globe 850 globe4x4
Notice GPS Globe 850 globe4x4GPS Globe 4X4
 
INS Vicenç Plantada Intercanvi 14 15
INS Vicenç Plantada Intercanvi 14 15 INS Vicenç Plantada Intercanvi 14 15
INS Vicenç Plantada Intercanvi 14 15 Carles López
 
Golf GIS facility management
Golf GIS facility managementGolf GIS facility management
Golf GIS facility managementGOMOGI
 
GPS Globe - Catalogue produits
GPS Globe - Catalogue produitsGPS Globe - Catalogue produits
GPS Globe - Catalogue produitsGPS Globe 4X4
 
AUDITORIA DE PROYECTO DE VUELO
AUDITORIA DE PROYECTO DE VUELOAUDITORIA DE PROYECTO DE VUELO
AUDITORIA DE PROYECTO DE VUELOelenabueno
 
Presente y futuro social media
Presente y futuro social mediaPresente y futuro social media
Presente y futuro social mediaIsmael El-Qudsi
 
Píldora 1: Android intro
Píldora 1: Android introPíldora 1: Android intro
Píldora 1: Android introhojalataverde
 

En vedette (20)

RgaSAT: Fiscalização de Serviços via Rastreio GPS Autônomo
RgaSAT: Fiscalização de Serviços via Rastreio GPS AutônomoRgaSAT: Fiscalização de Serviços via Rastreio GPS Autônomo
RgaSAT: Fiscalização de Serviços via Rastreio GPS Autônomo
 
Estudo 4square sp rj (1)
Estudo 4square   sp rj (1)Estudo 4square   sp rj (1)
Estudo 4square sp rj (1)
 
Checkins em Shopping Centers Brasil Pré e pós Natal
Checkins em Shopping Centers Brasil Pré e pós NatalCheckins em Shopping Centers Brasil Pré e pós Natal
Checkins em Shopping Centers Brasil Pré e pós Natal
 
Autoradio dvd gps android 4
Autoradio dvd gps android 4Autoradio dvd gps android 4
Autoradio dvd gps android 4
 
QRGeoLocation - um padrão de entrada de dados em sistemas GPS
QRGeoLocation - um padrão de entrada de dados em sistemas GPSQRGeoLocation - um padrão de entrada de dados em sistemas GPS
QRGeoLocation - um padrão de entrada de dados em sistemas GPS
 
Localizando o Foursquare nas Mídias Sociais
Localizando o Foursquare nas Mídias SociaisLocalizando o Foursquare nas Mídias Sociais
Localizando o Foursquare nas Mídias Sociais
 
Auf zur Bike Challenge Hohe Salve _2_.pdf
Auf zur Bike Challenge Hohe Salve _2_.pdfAuf zur Bike Challenge Hohe Salve _2_.pdf
Auf zur Bike Challenge Hohe Salve _2_.pdf
 
GPS - Global Positioning System
GPS - Global Positioning SystemGPS - Global Positioning System
GPS - Global Positioning System
 
Notice GPS Globe 850 globe4x4
Notice GPS Globe 850 globe4x4Notice GPS Globe 850 globe4x4
Notice GPS Globe 850 globe4x4
 
INS Vicenç Plantada Intercanvi 14 15
INS Vicenç Plantada Intercanvi 14 15 INS Vicenç Plantada Intercanvi 14 15
INS Vicenç Plantada Intercanvi 14 15
 
Golf GIS facility management
Golf GIS facility managementGolf GIS facility management
Golf GIS facility management
 
Trabalho sobre GPS III
Trabalho sobre GPS IIITrabalho sobre GPS III
Trabalho sobre GPS III
 
GPS Globe - Catalogue produits
GPS Globe - Catalogue produitsGPS Globe - Catalogue produits
GPS Globe - Catalogue produits
 
AUDITORIA DE PROYECTO DE VUELO
AUDITORIA DE PROYECTO DE VUELOAUDITORIA DE PROYECTO DE VUELO
AUDITORIA DE PROYECTO DE VUELO
 
17 gps
17  gps17  gps
17 gps
 
Presente y futuro social media
Presente y futuro social mediaPresente y futuro social media
Presente y futuro social media
 
Píldora 1: Android intro
Píldora 1: Android introPíldora 1: Android intro
Píldora 1: Android intro
 
Presentación ventures2015
Presentación ventures2015Presentación ventures2015
Presentación ventures2015
 
Open Data INS Tunisie- 2012
Open Data INS Tunisie- 2012Open Data INS Tunisie- 2012
Open Data INS Tunisie- 2012
 
Foursquare elisa teixeira
Foursquare elisa teixeiraFoursquare elisa teixeira
Foursquare elisa teixeira
 

Similaire à Formation JPA Java persistence API

#5 Java EE5 Client Lourd et Smart Client
#5 Java EE5  Client Lourd  et Smart Client#5 Java EE5  Client Lourd  et Smart Client
#5 Java EE5 Client Lourd et Smart ClientGuillaume Sauthier
 
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...ENSET, Université Hassan II Casablanca
 
introductionaudevcomposantdistribuejavaee.pdf
introductionaudevcomposantdistribuejavaee.pdfintroductionaudevcomposantdistribuejavaee.pdf
introductionaudevcomposantdistribuejavaee.pdfHamdaneAbdelAzizHagg
 
ToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & AgilitéToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & AgilitéNicolas Deverge
 
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01Eric Bourdet
 
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01 (1)
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01 (1)Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01 (1)
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01 (1)Eric Bourdet
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logiciellecyrilgandon
 
01_Introduction_a_JEE.pdf
01_Introduction_a_JEE.pdf01_Introduction_a_JEE.pdf
01_Introduction_a_JEE.pdfJunior724645
 
Support formation vidéo : OCA Java SE 8 Programmer (1Z0-808) (1)
Support formation vidéo : OCA Java SE 8 Programmer (1Z0-808) (1)Support formation vidéo : OCA Java SE 8 Programmer (1Z0-808) (1)
Support formation vidéo : OCA Java SE 8 Programmer (1Z0-808) (1)SmartnSkilled
 
react-slides.ppx (2) (1).pptx react presentation basic
react-slides.ppx (2) (1).pptx react presentation basicreact-slides.ppx (2) (1).pptx react presentation basic
react-slides.ppx (2) (1).pptx react presentation basiczineblahib2
 
Presentation JEE et son écossystéme
Presentation JEE et son écossystémePresentation JEE et son écossystéme
Presentation JEE et son écossystémeAlgeria JUG
 
Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2OW2
 
Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2Catherine Nuel
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPYouness Boukouchi
 

Similaire à Formation JPA Java persistence API (20)

2
22
2
 
#5 Java EE5 Client Lourd et Smart Client
#5 Java EE5  Client Lourd  et Smart Client#5 Java EE5  Client Lourd  et Smart Client
#5 Java EE5 Client Lourd et Smart Client
 
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...Support de cours EJB 3 version complète Par Mr  Youssfi, ENSET, Université Ha...
Support de cours EJB 3 version complète Par Mr Youssfi, ENSET, Université Ha...
 
introductionaudevcomposantdistribuejavaee.pdf
introductionaudevcomposantdistribuejavaee.pdfintroductionaudevcomposantdistribuejavaee.pdf
introductionaudevcomposantdistribuejavaee.pdf
 
ToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & AgilitéToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & Agilité
 
JavaEEGibello.ppt
JavaEEGibello.pptJavaEEGibello.ppt
JavaEEGibello.ppt
 
Support de cours entrepise java beans ejb m.youssfi
Support de cours entrepise java beans ejb m.youssfiSupport de cours entrepise java beans ejb m.youssfi
Support de cours entrepise java beans ejb m.youssfi
 
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01
 
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01 (1)
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01 (1)Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01 (1)
Supportdecoursejb3versioncompletemryoussfi 140317162653-phpapp01 (1)
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logicielle
 
01_Introduction_a_JEE.pdf
01_Introduction_a_JEE.pdf01_Introduction_a_JEE.pdf
01_Introduction_a_JEE.pdf
 
Support formation vidéo : OCA Java SE 8 Programmer (1Z0-808) (1)
Support formation vidéo : OCA Java SE 8 Programmer (1Z0-808) (1)Support formation vidéo : OCA Java SE 8 Programmer (1Z0-808) (1)
Support formation vidéo : OCA Java SE 8 Programmer (1Z0-808) (1)
 
react-slides.ppx (2) (1).pptx react presentation basic
react-slides.ppx (2) (1).pptx react presentation basicreact-slides.ppx (2) (1).pptx react presentation basic
react-slides.ppx (2) (1).pptx react presentation basic
 
Presentation JEE et son écossystéme
Presentation JEE et son écossystémePresentation JEE et son écossystéme
Presentation JEE et son écossystéme
 
Openstack framework Iaas
Openstack framework IaasOpenstack framework Iaas
Openstack framework Iaas
 
Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2
 
Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSP
 
Présentation1
Présentation1Présentation1
Présentation1
 
Liquibase en action
Liquibase en actionLiquibase en action
Liquibase en action
 

Formation JPA Java persistence API

  • 1. Author: Thibault Cuvillier – Creative Commons 2.0 Java Persistence API Auteur: Thibault Cuvillier Consultant indépendant cuvillier@gmail.com http://www.btcweb.com JP 1.1 - Template 1.0
  • 2. Contenu de la présentation • • • • • • Chap Chap Chap Chap Chap Chap 1: 2: 3: 4: 5: 6: Introduction Mapping objet relationnel – Niveau 1 EntityManager EJBQL – Niveau 1 Mapping objet relationnel – Niveau 2 EJBQL – Niveau 2 • Les questions et corrigés des TP sont accessibles sur mon site. • JPA 1, TP avec Hibernate 3.1 et Eclipse (pas mavenifié…) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 2
  • 3. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence Introduction JP 1.1 - Template 1.0
  • 4. Introduction à javax.persistence Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 4
  • 5. Accéder à la base de données Session Http • Les objets d'une application 1 peuvent être: * – Transitoires: ils ne survivent pas Caddie 1 à l'application * – Persistants: ils survivent à l'application Item 1 • Exemple: dans un système de * vente en ligne: Produit – La classe Caddie est transitoire, ne contenant que des informations sur la session – La classe produit est persistante dans une base de données. Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 5
  • 6. Les quatre modèles 1/2 transitoire Le modèle conceptuel La compréhension de l'utilisateur Le modèle logique Modèle objet Le modèle de présentation Les données présentées à l'utilisateur Thibault Cuvillier Creative Commons 2.0 Le modèle physique Schéma de la base javax.persistence / Introduction 6
  • 7. Les quatre modèles 2/2 • Les quatre modèles doivent être isomorphes – Intégration sémantique • Les relations entre les modèles sont des mappings • Mapping entre le modèle logique et le schéma d'une base de données relationnelle: – Mapping Objet Relationnel Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 7
  • 8. Le mapping objet-relationnel • Décrit la projection d'une classe dans un SGRBR • Exemple: – Une classe = Une table – Une propriété = Une colonne • Le mapping O/R est plus complique: – Comment projeter l'héritage ? – Comment projeter les relations entre objets ? – Comment projeter les types de données Java ? –… Suite • Il y a de nombreuses conceptions possibles… Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 8
  • 9. API de persistance avec JDBC / DAO 1/2 • Les objets persistants sont des JavaBeans • Vous y accédez via des DAO – Data Access Object • Implémente les méthodes de persistance: – Insérer, détruire, modifier, requêtes… PersonneDAO Personne prenom nom email Thibault Cuvillier Creative Commons 2.0 inserer détruire modifier requete(prenom, nom) javax.persistence / Introduction 9
  • 10. API de persistance avec JDBC/DAO 2/2 • La couche de persistance prend en charge le mapping O/R – Hard-codé en Java, Séparé des données Application Persistance POJO Mapping O/R • Mais: – Un objet peut être chargé deux fois en mémoire – La navigation entre objets est délicate à gérer – Les objets ne sont stockés en cache, générant un flux important de requêtes SQL Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 10
  • 11. Cache de persistance • L'ajout d'un cache permet: – De limiter le nombre de requêtes SQL – De ne conserver en mémoire qu'un seul exemplaire des objets persistants Application Persistance POJO Cache Mapping O/R • Mais, comment gérer les transactions ? Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 11
  • 12. Cache transactionnel • Le cache doit être transactionnel – Isolation transactionnelle – Consistance • Il doit être multi-thread safe Persistance POJO Application Cache Mapping O/R Gestion des transactions Gestion de la sécurité • Cette solution est complexe Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 12
  • 13. Outils de mapping O/R • Moteur de mapping générique – utilise une description du mapping • Cache transactionnel • Les objets persistants sont des POJOs • Un DAO générique mapping.xml Description du mapping O/R Persistance API Application Cache Mapping O/R Gestion des transactions Gestion de la sécurité Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 13
  • 14. Mapping objet relationnel • Produits de mapping objet / relationnels – Hibernate, JDO, Toplink (Oracle) • Ces produits savent: – Mapper une classe sur plusieurs tables, – Mapper des objets dépendants, – Mapper types complexes, – Mapper des relations, – Mapper l'héritage entre entités, – Gérer des caches locaux ou distribués. Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 14
  • 15. Exemple Hibernate 1/2 Client.hbm.xml <hibernate-mapping> <<Entity>> Client id prénom nom téléphone POJO <class name="com.btc.Client" table="CLIENT"> <property name="prénom"> <column name="PRENOM" length="32"/> </property> … </class> </hibernate-mapping> Mapping O/R <<Tables>> CLIENT ID PRENOM NOM TELEPHONE RUE 1 Adresse rue ville codePostal <<Table>> EMAIL 0..* EMail email Thibault Cuvillier Creative Commons 2.0 CLIENT_FK EMAIL javax.persistence / Introduction VILLE CODEPOSTAL Tables 15
  • 16. Exemple Hibernate 2/2 • Le code client devient simple et naturel: Session session = … ouvrir la session Hibernate …; Transaction tx = session.beginTransaction(); tx.begin(); Client client = new Client(); client.setPrénom("Bill"); client.setNom("Gates"); Adresse adresse = new Adresse("5 rue de l'église", "Lyon", "69002"); client.setAdresse(addresse); client.addEMail("bill@microsoft.com"); client.addEMail("bilou@microsoft.com"); session.save(client); tx.commit(); session.close(); Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 16
  • 17. javax.persistence • Nouvelle API Java de persistance – Implémentations avec Hibernate, JDO, Toplink ou autre – J2EE (module EJB ou Web) ou J2SE • package javax.persistence PersistenceContext – Fonctionne avec J2SE et J2EE PersistenceContext • Contexte de persistance: – Gère le cache des objets PersistenceContext – Transactionnel – Durée de vie: TRANSACTION ou EXTENDED – Une application peut utiliser plusieurs contextes Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 17
  • 18. Entités • Interface unifiée • Le descripteur de mapping O/R standard – Peut être généré à partir d'annotations Java5. @Entity public class Client extends Serializable { private long _id; private String _nom; @Id public long getId() { return _id; } public void setId(long id) { _id = id; } public String getNom() { return _nom; } public void setNom(String nom) { _nom = nom; } … } Cette entité est complète ! Mapping par défaut <<Tables>> CLIENT ID NOM Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 18
  • 19. Cycle de vie des Entités • Gérée = associée à un contexte de persistance Etat Dans la base Associé à un contexte de persistance Transitoire Non Non Existe Oui Oui Détaché Oui Non Détruit Non Oui Non Géré Transitoire Détaché Thibault Cuvillier Creative Commons 2.0 Géré dans un contexte persist cascade merge Existe find query EJBQL persist Détruit sérialisation fin de TX javax.persistence / Introduction 19
  • 20. Avantages des Entités • Objets persistants de faible granularité – Plus proche du modèle d'analyse • Mapping O/R puissant • Fonctionne avec J2EE et J2SE • Langage de Query: EJBQL • Accès direct à la connexion sous jacente – Pour optimisations – Pour utiliser des API spécifiques (Hibernate, JDO) • Permet de générer le schéma de la base à partir des annotations (pas recommandé) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 20
  • 21. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence Mapping Objet / Relationnel Niveau 1 JP 1.1 - Template 1.0
  • 22. Mapping OR Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 22
  • 23. Mapping O/R > Mapping simple • Mapping O/R Mapping simple Identité simple Callback Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 23
  • 24. Classe persistante • Doit être annotée avec @Entity @Entity(name="Compte" access=AccessType.PROPERTY) – name Nom de l'entité utilisé dans les expressions EJBQL select c from Compte c where c.solde < 0 – access Annotation des attributs persistants sur le getter (PROPERTY, par défaut) ou sur les attributs (FIELD) qui ne doivent pas être privés (à éviter!). • Doit avoir un constructeur par défaut Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 24
  • 25. Mapping 1 classe / 1 table 1/3 • Annotation @Table – name : Nom de la table, nom de la classe. – catalog : Catalogue de la table, celui de la ctx. – schema: Schéma de la table, celui de la ctx. • Pour générer le schéma: – UniqueContraint uniqueContraints[] Contraintes d'unicité simples ou composites – Annotation @UniqueContraint • columnNames: colonnes dans la contrainte Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 25
  • 26. Mapping 1 classe / 1 table 2/3 • Table: <schéma par défaut>.Client • Table: <schéma par défaut>.CLIENT_TBL • Table: FORMATION. CLIENT_TBL Thibault Cuvillier Creative Commons 2.0 @Entity public class Client implements Serializable { … } @Entity @Table(name="CLIENT_TBL") public class Client implements Serializable { … } @Entity @Table(name="CLIENT_TBL", schema="FORMATION") public class Client implements Serializable { … } javax.persistence / Introduction 26
  • 27. Mapping 1 classe / 1 table 3/3 • Table FORMATION.CLIENT_TBL + contrainte d'unicité sur (prenom, nom) et (telephone) @Entity @Table( name="CLIENT_TBL", uniqueConstraints={ @UniqueConstraint(columnNames={"nom", "prenom"}), @UniqueConstraint(columnNames={"telephone"})} ) public class Client implements Serializable { … } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 27
  • 28. Propriétés persistantes 1/2 • Doit avoir un des types suivants: – Type primaire Java: int, long, double … – String, BigInteger, BigDecimal, Date, Calendar, Date… – byte[], Byte[], char[], Character[] – enums Java5 (colonne integer ou String) – Classe Java sérializable (a éviter, voir + loin) – Classe Java dépendante (voir + loin) – Collection, Set, List, Map ou génériques List<T>… • Type de base, Entités. – Attention, les types de base ne peuvent être NULL Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 28
  • 29. Propriétés persistantes 2/2 • Déclarez les accesseurs public: – T getX() et void setX(T t) – boolean isX() et void setX(boolean b) • Peuvent ou non être déclarés dans l'interface • Ne doivent pas exécuter de logique métier • Si une exception est levée dans getX ou setX , la transaction rollback. private transient String _pwdDecrypté; • Attributs non persistant: Thibault Cuvillier Creative Commons 2.0 @Transient public String getPwdDecrypté() {…} javax.persistence / Introduction 29
  • 30. @Basic, @Temporal • Indique un mapping simple pour une propriété persistante – Par défaut, toutes les propriétés sont persistantes • @Basic – fetch = EAGER ou LAZY – optional = @Basic true ou false @Temporal(TemporalType.DATE} • @Temporal public Date getDateNaissance() { – value = TIMESTAMP , return _ddn; DATE, TIME } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 30
  • 31. Mapping 1 propriété / 1 colonne 1/3 • Utilisez l'annotation @Column – name: Nom de la colonne - Nom de la propriété – insertable : utilisée dans INSERT? - true – updatable : utilisée dans UPDATE? - true • Pour pouvoir générer le schéma: – nullable : peut être NULL? - true – unique : Valeur est unique dans la table - false – columnDefinition - Définition SQL de la colonne – length : longueur de la column - 255 – precision , scale pour les colonnes numérique - 0 Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 31
  • 32. Mapping 1 propriété / 1 colonne 1/3 • Colonne "NOM" VARCHAR(255) private String _nom; public String getNom() { return _nom; } public void setNom(String nom) { _nom = nom; } private String _nom; • Colonne "NAME" VARCHAR(32) @Column(name="NAME", length=32) public String getNom() { return _nom; } public void setNom(String nom) { _nom = nom; } private String _nom; • Colonne "NAME" VARCHAR(32) NOT NULL Thibault Cuvillier Creative Commons 2.0 @Column(name="NAME", length=32, nullable=false) public String getNom() { return _nom; } public void setNom(String nom) { _nom = nom; } javax.persistence / Introduction 32
  • 33. Mapping 1 propriété / 1 colonne 3/3 • Colonne "DESC" CLOB private String _desc; @Column(columnDescription="CLOB") public String getDesc() { return _desc; } public void setDesc(String desc) { _desc = desc; } private Time _time; • Colonne "TIME" TIMESTAMP @Column(columnDescription="TIMESTAMP") public Time getTime() { return _time; } public void setTime(Time time) { _time = time; } • Colonne "SOLDE"private double _solde; Non modifiable @Column(precision=12, updatable="false") public double getSolde() { return _solde; } public void setSolde(double solde) { _solde = solde; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 33
  • 34. Mapping O/R > Identité simple • Mapping O/R Mapping simple Identité simple Callback Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 34
  • 35. Identité • L'identité d'une Entité = Clef Primaire • Identité métier: – Identité simple = Une seule valeur – Identité composite = Plusieurs valeurs • Identité technique: une colonne neutre – Entier long – Séquence Oracle, Colonne automatique MySQL… ! L'identité d'une entité doit être invariable . Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 35
  • 36. Recommandations • N'utilisez que des Identificateurs neutres – Long ou long – Initialisation: séquence, table de compteurs, colonnes à incrémentation automatique… • Ajoutez si nécessaire des colonnes pour améliorer la performance des requêtes <<Table>> Soctété id nom prénom téléphone sociétéId id nom Thibault Cuvillier Creative Commons 2.0 <<Table>> Facture <<Table>> Client id clientId sociétéId montantHT montantTTC tva javax.persistence / Introduction 36
  • 37. Identité simple 1/4 • La propriété contenant l'identité: @Id • Pour une identité technique générée: • @GeneratedValue – strategy NONE: pas de génération - Valeur par défaut TABLE: utilisation d'une table pour gérer les ID SEQUENCE: utilisation de séquences (Oracle par ex.) IDENTITY: génération de la valeur par la base AUTO: génération par le fournisseur de persistance – String generator (Si generate != NONE) Nom du générateur Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 37
  • 38. Identité simple 2/4 • La valeur de l'ID est contrôlée par l'application @Id public long getId() { return _id; } @Id • La valeur de l'ID est fixée lors d'un INSERT par une séquence. @GeneratedValue(strategy=GenerationType.SEQUENC E, generator="CLIENT_ID_SEQ") @SequenceGenerator( name="CLIENT_ID_SEQ", sequenceName="CLIENT_ID", initialValue=0, allocationSize=50) public long getId() { return _id; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 38
  • 39. Identité simple 3/4 • Les ID sont générés à partir de la table IDGEN possédant une colonne ID_KEY (PK), ID_VAL. • La valeur de l'ID suivant utilise la clef "CLIENT_ID". @Id @GeneratedValue( strategy=GenerationType.TABLE, generator="CLIENT_ID_TBL") @TableGenerator( name="CLIENT_ID_TBL", table="IDGEN", pkColumnName="ID_KEY", valueColumnName="ID_VAL", pkColumnValue="CLIENT_ID", initialValue=1, allocationSize=25) public long getId() { return _id; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 39
  • 40. Identité simple 4/4 • La valeur de l'ID est générée par la base, par une colonne à incrémentation automatique • Colonne Automatic MySQL, Identity HsQL @Id @GeneratedValue(strategy=GenerationType.IDENTITY) public long getId() { return _id; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 40
  • 41. Mapping O/R > Callbacks • Mapping O/R Mapping simple Identité simple Callback Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 41
  • 42. Callbacks • Méthodes déclenchées pour notifier les changements d'états d'une entité @Entity public class Login { private String password; private String cryptedPassword; @PrePersist @PreUpdate public void preUpdate() { cryptedPassword = crypt(password); } } Thibault Cuvillier Creative Commons 2.0 @PostLoad public void postLoad() { password = decrypt(cryptedPassword); } … javax.persistence / Introduction 42
  • 43. Callbacks des entités • @PrePersist et @PostPersist – Appelé avant et après EntityManager.persist() • @PreRemove et @PostRemove – Appelé avant et après EntityManager.remove() • @PreUpdate et @PostUpdate – Appelé avant et après une maj dans la base • @PostLoad – Appelé après le chargement de l'entité Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 43
  • 44. Listener d'entité • Vous pouvez mettre le code des callbacks dans un listener avec @EntityListener. Personne.java @Entity @EntityListener(com.btc.LogListener) public class Personne { …} ! Les listeners sont hérités ! LogListener.java public class LogListener { L'entité est passée en @PrePersist ! paramètre public void prePersist(Object o) { System.out.println("PrePersit(o=" + o+")"); } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 44
  • 45. Travaux pratiques • Ouvrez le projet JP-Lab01-Mapping-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 45
  • 46. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence EntityManager JP 1.1 - Template 1.0
  • 47. EntityManager Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 47
  • 48. EntityManager • Permet de changer l'état persistant des entités – Création, destruction, modification • Associé à un contexte de persistance • Permet d'exécuter des requêtes – EJBQL: select c from client c where c.nom=:nom – Permet de fermer le contexte de persistance (J2SE) – Permet de contrôler les transactions (J2SE ou pas JTA) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 48
  • 49. Création d'un EntityManager avec J2SE Attention, différent pour • L'EntityManager est créé par une un serveur J2EE factory • La factory contient la description du mapping EntityManagerFactory factory = Persistence.createEntityManagerFactory( "em", new Properties()); EntityManager em = factory.createEntityManager(); • Vous pouvez utiliser plusieurs contextes de persistance dans votre application – Une factory par contexte de persistence Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 49
  • 50. persistence.xml • La factory est décrite dans le fichier Transactions: META-INF/persistence.xml •RESOURCE_LOCAL •JTA <?xml version="1.0" encoding="UTF-8"?> <persistence> <persistence-unit name="em" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value="root"/> <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1/db"/> </properties> </persistence-unit> Attention avec un serveur J2EE, </persistence> utilisation de JNDI et de JTA Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 50
  • 51. TRANSACTION et EXTENDED 1/2 • Le contexte de persistance maintient les données en cache. • Le cache peut avoir deux durées de vie: – TRANSACTION Les caches sont vidés à la fin de chaque transaction – EXTENDED Les caches sont vidés lorsque le contexte est fermé • Le cache peut être paramétré – Annotations et paramétrage XML non standard – Dépend de l'implémentation Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 51
  • 52. TRANSACTION et EXTENDED 2/2 • Pour créer un EntityManager EXTENDED: EntityManagerFactory factory = Persistence.createEntityManagerFactory( "em", new Properties()); EntityManager em = _factory.createEntityManager( PersistenceContextType.EXTENDED ); … em.close(); • Il est préférable d'utiliser des caches transactionnels et de reposer ainsi sur l'isolation transactionnelle de la base Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 52
  • 53. EntityManager.find • EntityManager.find(Class c, Object id) – Charge un objet en mémoire et le retourne • EntityManager.getReference(Class c, Object id) – Ne charge pas l'objet en mémoire, ne contient que l'ID. – L'état sera chargé lors du premier accès à une propriété persistante EntityManager em = … on verra plus loin …; Client client = em.getReference(Client.class, "Bill Gates"); em.remove(client); Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 53
  • 54. Gérer les transactions EntityManager em = …; • Pas de transactions EntityTransaction tx = imbriquées em.getTransaction(); • S'il n'y a pas de transaction, tx.begin(); le contexte de persistance, try { … modifier les données … la méthode find: tx.commit(); – en commence une } catch(Exception e) { tx.rollback(); – la termine à la fin de la throw e; méthode } – retourne une entité détachée • Pour modifier les données dans la base, il suffit de modifier un objet géré Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 54
  • 55. EntityManager.persist 1/2 • void persist(Object entity) Etat Action Transitoire Insertion dans la base (1) Géré Rien sur l'entité(1) Détaché IllegalArgumentException Détruit L'entité redevient managée (1) – (1) Cascade sur les entités référencées si cascade=PERSIST ou ALL Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 55
  • 56. EntityManager.persist 2/2 • Exemple: EntityManager em = …; EntityTransaction tx = em.getTransaction(); tx.begin(); Client client = new Client(); client.setPrénom("Harry"); client.setNom("Cover"); client.setTéléphone("0404040404"); em.persist(client); tx.commit(); System.out.println("Client id = " + client.getId()); Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 56
  • 57. EntityManager.remove • void remove(Object entity) Etat Action Transitoire Rien sur l'entité, mais cascade (1) Géré Destruction de l'entité et cascade (1) Détaché IllegalArgumentException Détruit Rien – (1) Cascade sur les entités référencées si cascade=REMOVE ou ALL Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 57
  • 58. EntityManager.merge • <T> T merge(T entity) – Retourne une nouvel entité géré ! Attention, avec Hibernate, provoque une lecture de l'objet pour comparer son état. Etat Transitoire Géré Action Création de l'entité (1) Rien sur l'entité (1) Détaché Copie de l'état dans une entité gérée avec la même identité (1) IllegalArgumentException Détruit – (1) Cascade sur les entités référencées si cascade=MERGE ou ALL javax.persistence / Introduction Thibault Cuvillier Creative Commons 2.0 58
  • 59. EntityManager.merge: exemple • La méthode fetch retourne l'objet persistant et le rend détache du contexte de persistance. • La méthode save met à jour l'objet dans le contexte de persistance. • fetch et save sont des méthodes transactionnelles public Client fetchClient(long idclient) { EntityManager em = …; return em.find(Client.class, idclient); } Ne pas utiliser getReference: pourquoi ? public void saveClient(Client client) { EntityManager em = …; em.merge(client); } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 59
  • 60. Objets détachés • Un objet persistant devient détaché quand: – Le contexte de persistance se termine: • TRANSACTION: Fin de la transaction • EXTENDED: Fermeture explicite du contexte – Quand l'objet est sérialisé • Passage par valeur pour les interfaces Remote – Quand l'objet est cloné EJB Session EntityManager Navigateur Web GET EditClient.jsp Client c = fetchClient("Bill Gates") find SELECT POST EditClient.jsp saveClient(c) merge UPDATE Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction Base 60
  • 61. Transactions optimistes 1/2 • Un objet peut être modifié entre sa lecture et son merge par une autre requête – La dernière écriture gagne • Transaction longue – Gestion pessimiste: vous devez gérer le verrouillage – Gestion optimiste: vous ajoutez une propriété Version • La version est incrémentée à chaque modification – Lors du merge, le contexte de persistance vérifie si le numéro de version a changé. – Exception dans ce cas, et rollback de la transaction Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 61
  • 62. Transactions optimistes 2/2 • Il faut identifier la propriété contenant le numéro de version avec @Version – Peut être du type: int, Integer, long, Long, short, Short, Timestamp public Person { private long _version; @Version public long getVersion() { return _version; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 62
  • 63. Mise à jour de la base de données • La base de donnée est mise à jour lors du commit ou avant l'exécution d'une query • Pour forcer la mise à jour: – EntityManager.flush() – Exécute le SQL • Vous pouvez recharger l'état d'un objet modifié à partir de la base: – EntityManager.refresh(Objet o) – Annule les modifications apportées Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 63
  • 64. Travaux pratiques • Ouvrez le projet JP-Lab02-EntityManagerQuestion – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 64
  • 65. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence EJBQL Niveau 1 JP 1.1 - Template 1.0
  • 66. EJBQL Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 66
  • 67. Queries EJBQL simples • EJBQL permet d'exécuter des requêtes – Pour lire des données – De faire des UPDATE et DELETE en masse • Utilise le nom des entités et des propriétés – Pas le nom des tables et colonnes – Attribut name de l'annotation @Entity – Abstract Schema Name select c from Client c where c.name="Alonso Bistrot" Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 67
  • 68. La clause SELECT • SELECT c from Client c – Retourne tous les clients • SELECT c.name, c.email from Client c – Retourne le noms et l'email de tous les clients • SELECT COUNT(c) from Client c – Retourne le nombre de clients • SELECT AVG(c.age) from Client c – Retourne l'age moyen des clients – Autres fonctions: SUM, MIN, MAX Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 68
  • 69. DISTINCT, ORDER BY, NEW • Select DISTINCT c.name from Client c – Retourne une liste de nom unique • Select c from Client c order by c.name ASC – Retourne la liste des clients triés par ordre alpha. – Ascendant: ASC (par défaut), Descendant: DESC • Permet de retourner une liste d'objets Java quelconque – Pas forcément des entités select new com.btc.EmployeInfo(e.id, e.status, e.salaire) from Employe e Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 69
  • 70. Opérateurs de la clause WHERE 1/2 • [NOT] BETWEEN – WHERE c.age BETWEEN 0 and 17 – Equivalent à: c.age >= 0 AND c.age <= 17 • [NOT] LIKE – select c from Client c where c.name LIKE 'B%' – select c from Client c where c.name LIKE 'B_ _ _' • [NOT] IN – select c from Commande c where c.status IN('E', 'A', 'B') • IS [NOT] NULL – select c from Client c where c.status IS NULL Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 70
  • 71. Fonctions EJBQL • CONCAT("a", "b") => "ab" • TRIM([BOTH, " ", ]" a ") => "a" – 1er argument: BOTH, LEADING, TRAILING • • • • • • • • • LOWER("A") => "a" UPPER("a") => "A" LOCATE("ababab", "b" [, 3]) => 4 LENGTH("abcd") => 4 SUBSTRING("abcde", 2, 3) => "bcd" ABS(-2) => 2 SQRT(4) => 2 MOD(101, 10) => 1 SIZE(c.commandes) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 71
  • 72. Opérateurs de la clause WHERE 3 • EXISTS – Vrai si la sous-requête retourne au moins un objet SELECT DISTINCT emp FROM Employee emp WHERE EXISTS ( SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp = emp.spouse) • ALL, ANY (ou SOME) – ALL: Vrai si toutes les valeurs remplissent la condition – ANY: Vrai si une valeur au moins remplie la condition SELECT emp FROM Employee emp WHERE emp.salary > ALL ( SELECT m.salary FROM Manager m WHERE m.department = emp.department) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 72
  • 73. GROUP BY • GROUP BY permet de regrouper les valeurs retournées par la requête • Requête sans clause GROUP BY: Entreprise SUN Montant 5500 IBM SUN 4500 7100 Entreprise Montant SUN 17100 IBM 17100 SUN 17100 Entreprise Montant IBM 4500 SUN 12600 select v.entreprise, SUM(v.montant) from Vente v • Requête avec la clause GROUP BY: select v.entreprise, SUM(v.montant) from Vente v group by c.entreprise Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 73
  • 74. HAVING • Permet de tester des valeurs agrégées – Impossible dans une clause WHERE select v.entreprise, SUM(v.montant) from Vente v group by v.entreprise having sum(v.montant) > 10000 Thibault Cuvillier Creative Commons 2.0 Entreprise Montant SUN 12600 javax.persistence / Introduction 74
  • 75. DELETE et UPDATE • Permet de déclencher des delete et update de masse dans un batch. • DELETE: • UPDATE: delete from Client c where c.status = 0 update Employe c set c.salary = 1500 where c.salary < 1500 • Le contexte de persistance n'est pas mis à jour • Utiliser: – Dans une transaction séparée – Au début d'une nouvelle transaction Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 75
  • 76. Exécuter une requête simples • Les requêtes simples public List findClients(EntityManager em) { Query query = em.createQuery ("select c from Client c"); return query.getResultList (); } • Avec des paramètres public List findClientsParStatus(EntityManager em, int status) { Query query = em.createQuery("select c from Client c where c.status = :status"); query.setParameter("status", status); return query.getResultList(); } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 76
  • 77. Requêtes nommées • Déclarer les requêtes dans une annotation @NamedQueries( @NamedQuery( name="getByName", query="select e from Entreprise where name=:name"), @NamedQuery(name="getAll", query="select e from Entreprise") ) public class EntrepriseMgr { public List<Entreprise> getEntreprises() { Query query = _em.createNamedQuery("getAll"); return query.getResultList(); } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 77
  • 78. Utiliser le SQL natif • Vous pouvez utiliser des requêtes SQL public List getClients() { Query query = _em.createNativeQuery ("select * from client", Client.class); return query.getResultList(); } • Vous pouvez utiliser @NamedNativeQuery Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 78
  • 79. Mapping d'un ResultSet • Vous pouvez mapper chaque colonne sur une ou plusieurs classes – Pas forcément des entités @SqlResultSetMapping( name="getClientsSummariesResults ", entities=@EntityResult(entityClass=com.valtech.ClientSummary, fields={ FieldResult(name="id" column="client_id"), FieldResult(name="name" column="client_name") }) ) public List getClientSummaries() { return _em.createNativeQuery( "select c.id as client_id, c.name as client_name from client c", " getClientsSummariesResults "). getResultList(); } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 79
  • 80. Travaux pratiques • Ouvrez le projet JP-Lab03-EJBQL-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 80
  • 81. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence Mapping O/R Niveau 2 JP 1.1 - Template 1.0
  • 82. Mapping avancé Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 82
  • 83. Mapping des relations Mapping avancé Mapping des relations Mapping de l'héritage Autres mappings Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 83
  • 84. Relations entre Entités • Support des relations 1-1, 1-n, n-m • Les relations peuvent uni ou bidirectionnelles • Certaines opérations peuvent se propager au travers des relations – Cascade: remove, persist, merge … remove – Que sur les relations OneToOne ou OneToMany Commande remove Ligne1 Thibault Cuvillier Creative Commons 2.0 remove Ligne2 javax.persistence / Introduction remove Ligne3 84
  • 85. Relation 1-1 Map sur la table PERSONNE Propriétaire de la relation @Entity public class Personne { private long _id; private Login _login; @OneToOne public Login getLogin() { return _login; } public void setLogin(Login login) { _login = login; } Map sur la colonne ID Map sur la table LOGIN @Entity public class Login { private Personne _personne; private String _login; private Stirng _password; @OneToOne(mappedBy="login") public Personne getPersonne() { return _personne; } public void setPersonne(Personne p) { _personne = p; } } PERSONNE contient une FK sur LOGIN colonne = <Propriété>_<column PK> = LOGIN_ID Thibault Cuvillier Creative Commons 2.0 Optionnel si la relation est unidirectionnelle } javax.persistence / Introduction 85
  • 86. Annotation OneToOne • @OneToOne – (O) String mappedBy = "" Propriété propriétaire de la relation – (O) boolean optional = true Peut ou non être null – (O) targetEntity = type de la propriété Le type de l'entité référencée – (O) CascadeType [] cascade = {} Opérations à cascader au travers de la relation: ALL, PERSIST, REMOVE, REFRESH – (O) fetchType fetch = EAGER Accès aux entités en mode LAZY ou EAGER Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 86
  • 87. Fetch des entités • EAGER: – Les objets liés sont chargés en une seule requête SQL 1 find(Personne.class, id) 2 getLogin() EntityManager Personne Login • LAZY: – Chargement de l'identité – Chargement de l'état lors du premier accès 1 find(Personne.class, id) 2 getLogin() Thibault Cuvillier Creative Commons 2.0 EntityManager Personne javax.persistence / Introduction Login 87
  • 88. Relation 1-n Map sur la table LOGIN Propriétaire de la relation @Entity public class Login { private long _id; private Role _role; Map sur la colonne ID Map sur la table ROLE @Entity public class Role { private long _id; private List<Login> _logins; @ManyToOne public Role getRole() { return _role; } public void setRole(Role r) { _role = r; } Optionnel si la relation est unidirectionnelle @OneToMany(mappedBy="role") public List<Login> getLogins() { return _logins; } public void setLogins(List<logins> l) { _logins = l; } } } LOGIN contient une FK sur ROLE colonne = <Propriété>_<column PK> = ROLE_ID Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 88
  • 89. Intégrité des relations • C'est au développeur d'assurer l'intégrité des relations – Positionner la relation inverse Login login = new Login(); Person person = new Person(); – Lors du chargement, le lien inverse est positionné login.setPerson(person); automatiquement person.setLogin(login); • Une relation est mise à jour dans la base à partir de son propriétaire Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 89
  • 90. Annotations ManyToOne et OneToMany • ManyToOne: même attributs que OneToOne • OneToMany: même attributs que OneToOne – Sauf fetch qui vaut LAZY • Avec les collections génériques: @OneToMany(mappedBy="role") List<Personne> getPersonnes() {…} • Avec les collections non génériques: @OneToMany(targetEntity=Personne.class, mappedBy="role") List getPersonnes() {…} Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 90
  • 91. Relation n-m Map sur la table ROLE Propriétaire de la relation @Entity public class Role { private long _id; private List<Authorization> _authorizations; @ManyToMany public List<Authorization> getAuthorizations() { return _authorizations; } public void setAuthorization(List<Authorization> a) { _authorizations = a; } } Map sur la table AUTHORIZATION Map sur la colonne ID @Entity public class Authorization { private long _id; private List<Role> _roles; Optionnel si la relation est unidirectionnelle @ManyToMany(mappedBy="authorizations") public List<Role> getRoles() { return _roles; } public void setRoles(List<Role> r) { _roles = r; } Table d'association: ROLE_AUTORIZATIONS PK: ROLE_ID PK: AUTHORIZATIONS_ID } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 91
  • 92. Mapping d'une clé étrangère 1/2 Jointure composite Jointure simple @Entity public class Login { private long _id; private Role _role; @ManyToOne @JoinColumn( name="ROLE_FK") public Role getRole() { return _role; } } Thibault Cuvillier Creative Commons 2.0 @Entity public class Entreprise { private long _id; private Personne _pdg; @ManyToOne @JoinColumns( { @JoinColumn(name="PDG_FIRST_NAME_PK", referencedColumnName="FIRST_NAME"), @JoinColumn(name="PDG_LAST_NAME_PK") referencedColumnName="FIRST_NAME"), }) public Personne getPDG() { return _pdg; } } 92 javax.persistence / Introduction
  • 93. Mapping d'une clé étrangère 2/2 • @JoinColumn – (O) String name Nom de la colonne contenant la clef étrangère. Par défaut: <Propriété du référant>_<PK du référé> – (O) String referencedColumnName Clef primaire dans la table du référencé – (O) boolean unique = false – (O) boolean nullable = true – (O) insertable = true – (O) updatable = true – (O) columnDefinition – (O) secondaryTable (on verra plus loin) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 93
  • 94. Mapping d'une table d'association • @JoinTable permet de préciser le nom de la table d'association @ManyToOne @JoinTable( name="ENTREPRISE_PDG", joinColumns = @JoinColumn(name="PDG_FK", referencedColumnName="ID"), inverseJoinColumns = @JoinColumn(name="ENT_FK", referencedColumnName="ID") ) public Personne getPDG() { return _pdg; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 94
  • 95. Mapper une HashMap • Permet de mapper la valeur des clefs d'une Map – @MapKey: name contient le nom de la propriété persistante qui formera la clef – Par défaut: la clef primaire @OneToMany @MapKey(name="id") public Map<PersonneID, Personne> getEmployés() { return _employés; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 95
  • 96. Ordre des relations • Permet d'ordonner les objets liés en fonction d'un ou plusieurs propriétés. • @OrderBy – Par défaut: la PK ASC @Entity public class Role { @Id long _id; private List<Login> _logins; @OneToMany(mappedBy="role") @OrderBy("user ASC") public List<Login> getLogins() { return _logins; } public void setLogins(List<logins> l) { _logins = l; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 96
  • 97. BLOB et CLOB • Permet de préciser le type d'une colonne contenant un Large OBject @Entity – Propriété String public class Role { CLOB: données texte private JPEGImage _image; – Autre type de donnée @Lob BLOB: données binaires • fetch: EAGER ou @Basic(fetch=FetchType.LAZY) public JPEGImage getPhoto() { LAZY return _image; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 97
  • 98. Travaux pratiques • Ouvrez le projet JP-Lab04-Relation-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 98
  • 99. Mapping de l'héritage Mapping avancé Mapping des relations Mapping de l'héritage Autres mappings Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 99
  • 100. Héritage • Une entité peut hériter d'une autre entité – Héritage des propriétés – Héritage des relations – Requêtes EJBQL polymorphes • Une entité peut être abstraite – Jamais instanciée – Possède un mapping O/R – Peut faire la cible de requêtes polymorphes • Une entité peut hériter d'une classe Java qui n'est pas une entité Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 100
  • 101. Une table par hiérarchie • Une colonne donne le type de l'objet: – Le discriminant • Requête polymorphe: – select v from Voiture v where v.couleur ='rouge' Voiture id couleur 0..n 1 Berline barresDeToit Attention, toutes les propriétés doivent être nullable. Personne Cabriolet toit=capote, hardtop VOITURE disc Thibault Cuvillier Creative Commons 2.0 propriétaire id couleur proprietaire javax.persistence / Introduction barresDeToit toit 101
  • 102. Une table par hiérarchie: exemple @Entity @Inheritance( strategy=SINGLE_TABLE) @DiscriminatorColumn(discriminatorType=STRING ) public abstract class Voiture { @Id long _id; private Personne _propriétaire; STRING, CHAR, private String _couleur; INTEGER … } • Chaque sous classe doit utiliser une valeur différente du discriminateur @Entity @DiscriminatorValue("B") public class Berline extends Voiture { private boolean barresDeToit; @Entity @DiscriminatorValue("C") public class Cabriolet extends Voiture { public enum Toit {HARDTOP, CAPOTE}; private Toit _toit; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 102
  • 103. Une table par classe concrète • Consomme peu de place disque • Requêtes polymorphes coûteuses Voiture id couleur propriétaire 0..n 1 Berline Personne Cabriolet barresDeToit toit=capote, hardtop Le support de ce mapping est optionnel CABRIOLET BERLINE id couleur proprietaire Thibault Cuvillier Creative Commons 2.0 barresDeToit id couleur javax.persistence / Introduction proprietaire toit 103
  • 104. Une table par classe concrète: exemple @Entity @Inheritance(strategy=TABLE_PER_CLASS) public abstract class Voiture { @Id long _id; private Personne _propriétaire; private String _couleur; … } @Entity public class Berline extends Voiture { private boolean barresDeToit; @Entity public class Cabriolet extends Voiture { public enum Toit {HARDTOP, CAPOTE}; private Toit _toit; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 104
  • 105. Une table par classe • Proche du modèle objet • Performance des requêtes Voiture id couleur propriétaire 0..n Personne 1 Berline Cabriolet barresDeToit toit=capote, hardtop VOITURE id couleur proprietaire BERLINE id Thibault Cuvillier Creative Commons 2.0 barresDeToit javax.persistence / Introduction CABRIOLET id toit 105
  • 106. Une table par classe: exemple @Entity @Inheritance(strategy=JOINED ) public abstract class Voiture { @Id long _id; private Personne _propriétaire; private String _couleur; … } @Entity public class Berline extends Voiture { private boolean barresDeToit; } • Les sous classes contiennent une FK sur la classe de base • Peut être renommée avec @PrimaryKeyJoinColum n @Entity public class Cabriolet extends Voiture { public enum Toit {HARDTOP, CAPOTE}; private Toit _toit; } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 106
  • 107. Travaux pratiques • Ouvrez le projet JP-Lab05-Inheritance-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 107
  • 108. Autres mappings Mapping avancé Mapping des relations Mapping de l'héritage Autres mappings Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 108
  • 109. Les classes embedded • Classe Java contenant une partie de l'état de l'entité @Embeddable public class Adresse { – Toujours un lien 1:1 @Entity Personne public class Personne { private Adresse _adresse; Adresse Colonnes de la table PERSONNE private String _rue; private String _ville; … } @Embedded @AttributeOverrides( { @AttributeOverride(name="rue", column=@Column(name="street")), @AttributeOverride(name="ville", column=@Column(name="city")) }) public Adresse getAdresse() { return _adresse; } public void setAdresse(Adresse adresse) { _adresse = adresse; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 109
  • 110. Super classe mappées • Factorise des mapping communs entre classes • Pas d'annotation pour contrôler l'héritage – La super-classe est intégrée @MappedSuperclass public class Personne { dans la définition de private String _prénom; private String _nom; la sous classe @Entity @AttributeOverride( name="NomDeFamille", column = @Column(name="NOM2FAMILLE")) public class Employe extends Personne { private String _matricule; public String getMatricule() {…} } Thibault Cuvillier Creative Commons 2.0 public String getPrenom() {…} @Column(name="NOM") public String getNomDeFamille() {…} } javax.persistence / Introduction 110
  • 111. Identité composite 1/2 • L'identité d'une Entité peut être encapsulé dans une classe – Bonne pratique: pourquoi ? • Deux solutions: @Embeddable public class PersonneID { private String _nom; @Entity public class Personne { L'identificateur mapprivate Date _ddn; sur une propriété … private PersonneID _id; public int hashCode() {…} public boolean equals(Object o) {…} @EmbeddedId } public PersonneID getID() { return _id; } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 111
  • 112. Identité composite 2/2 • Chaque propriété de l'identificateur map sur une propriété de l'entité @Entity @IdClass(ClientID.class) public class Client { private String _nom; private String _prenom; public class ClientID implements Serializable { private String _nom; private String _prenom; public ClientID() {} public getNom() {…} … public long hashcode() { … } public boolean equals(Object o) { … } public String getNom() { return _nom; } … } } Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 112
  • 113. Mapper une classe sur plusieurs tables @Entity @Table(name="PERSONNE") @SecondaryTable( name="PERSONNE_DETAILS", pkJoinColumn=@PrimaryKeyJoinColumn( name="PERSONNE_FK")) public class Personne { private long _id; private String _prénom; private String _nom; private String _couleurYeux; private String _couleurCheuveux; @Column( name="COULEUR_YEUX", table="PERSONNE_DETAILS) public String getCouleurYeux() {…} public String getCouleurCheuveux() {…} } Thibault Cuvillier Creative Commons 2.0 • L'entité est répartie sur plusieurs tables • Plus d'une table secondaire: – @SecondaryTables PERSONNE id PRENOM … PERSONNE_DETAILS PERSONNE_FK COULEUR_YEUX javax.persistence / Introduction … 113
  • 114. Travaux pratiques • Ouvrez le projet JP-Lab06-Embedded-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 114
  • 115. Author: Thibault Cuvillier – Creative Commons 2.0 javax.persistence EJBQL Niveau 2 JP 1.1 - Template 1.0
  • 116. EJBQL avancé Introduction à javax.persistance Mapping EntityManager EJBQL Mapping avancé EJBQL avancé Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 116
  • 117. Opérateurs sur les relations • IN(<Relation ToMany>) – Jointure entre deux entités – select c from Commande c, IN(c.lignes) l WHERE l.produit = 'Imprimante' • IS [NOT] EMPTY – select c from Commande c where c.lignes IS EMPTY • [NOT] MEMBER OF – Tester si une entité est ou non membre d'une relation Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 117
  • 118. Les jointures SQL • Un JOIN permet de combiner les lignes de plusieurs tables • Deux types de jointures EJBQL: – [INNER] JOIN – LEFT [OUTER] JOIN • Prenons un exemple: id 1 2 3 Client nom John Doeuf Alain Disoir Sophie Fonfec Thibault Cuvillier Creative Commons 2.0 id 10 11 12 13 Commande client nom 1 Imprimante 2 Souris 2 Ecran null Clé USB javax.persistence / Introduction 118
  • 119. INNER Join • Ne retourne pas les valeurs nulles de l'entité jointe – Il n'y a pas Sophie Fonfec dans le résultat ! • select c.nom, p.nom from Client c INNER JOIN c.produits p c.nom p.nom John Doeuf Alain Disoir Alain Disoir Imprimante Souris Ecran • Equivalent: – select c.nom, p.nom from Client JOIN c.produits p – select c.nom, p.nom from Client IN(c.produits) p javax.persistence / Introduction Thibault Cuvillier Creative Commons 2.0 119
  • 120. LEFT OUTER JOIN • Retourne aussi les valeurs null de l'entité jointe • select c.nom, p.nom from Client c LEFT OUTER JOIN c.produits p c.nom John Doeuf Alain Disoir Alain Disoir Sophie Fonfec p.nom Imprimante Souris Ecran null • Equivalent: – select c.nom,p.nom from Client c LEFT JOIN c.produits p Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 120
  • 121. FETCH • select p from Produit p JOIN p.client c – Lit les clients et produits en trois requêtes select p from Produit p JOIN p.client c load com.btc.join.Client load com.btc.join.Client Produit Imprimante Souris Ecran • select p from Produit p JOIN FETCH p.client c – Lit les clients et produits en une seule requête select p from Produit p JOIN p.client c Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 121
  • 122. Sous-requêtes EJBQL • Une requête peut contenir une sous-requête SELECT c FROM Customer c WHERE ( SELECT COUNT(o) FROM c.orders o ) > 10 SELECT goodCustomer FROM Customer goodCustomer WHERE goodCustomer.balance > ( SELECT avg(c.balance) FROM Customer c ) Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 122
  • 123. Travaux pratiques • Ouvrez le projet JP-Lab07-EJBQL2-Question – Suivez les instructions Thibault Cuvillier Creative Commons 2.0 javax.persistence / Introduction 123