plan de cette partie jpa 2.0 présentation de jpa (java...

29
1 JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia Antipolis Version Oral 0.9.1 – 26/11/11 Richard Grin R. Grin JPA page 2 Plan de cette partie Présentation de JPA Entité persistante Gestionnaire d’entités Compléments sur les entités : identité, associations, héritage Langage d’interrogation Exceptions Modifications en volume Transaction Concurrence R. Grin JPA page 3 Présentation de JPA R. Grin JPA page 4 JPA Partie de EJB pour la persistance des composants dans une BD relationnelle Peut aussi être utilisé par une application autonome, en dehors de tout serveur d’applications API ORM (Object-Relational Mapping) standard pour la persistance des objets Java R. Grin JPA page 5 Fournisseur de persistance L’utilisation de JPA nécessite un fournisseur de persistance qui implémente les classes et méthodes de l’API EclipseLink est le fournisseur de persistance de l’implémentation de référence de JPA R. Grin JPA page 6 Entité Classe dont les instances peuvent être persistantes Marquée par l’annotation @Entity « entité » pourra aussi désigner une instance de classe entité

Upload: others

Post on 24-Aug-2020

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

1

JPA 2.0(Java Persistence API)

pour Java EE 6Université de Nice - Sophia Antipolis

Version Oral 0.9.1 – 26/11/11Richard Grin

R. Grin JPA page 2

Plan de cette partiePrésentation de JPAEntité persistanteGestionnaire d’entitésCompléments sur les entités : identité, associations, héritageLangage d’interrogationExceptionsModifications en volumeTransactionConcurrence

R. Grin JPA page 3

Présentation de JPA

R. Grin JPA page 4

JPA

Partie de EJB pour la persistance des composants dans une BD relationnellePeut aussi être utilisé par une application autonome, en dehors de tout serveur d’applicationsAPI ORM (Object-Relational Mapping) standard pour la persistance des objets Java

R. Grin JPA page 5

Fournisseur de persistance

L’utilisation de JPA nécessite un fournisseur de persistance qui implémente les classes et méthodes de l’APIEclipseLink est le fournisseur de persistance de l’implémentation de référence de JPA

R. Grin JPA page 6

Entité

Classe dont les instances peuvent être persistantesMarquée par l’annotation @Entity« entité » pourra aussi désigner une instance de classe entité

Page 2: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

2

R. Grin JPA page 7

Exemple d’entité – identificateur et attributs

@Entitypublic class Departement {@Id@GeneratedValueprivate int id;private String nom;private String lieu;

Clé primaire dans la base

généréeautomatiquement

R. Grin JPA page 8

Exemple d’entité – constructeurs

/*** Constructeur sans paramètre obligatoire*/public Departement() { }

public Departement(String nom,String lieu) {

this.nom = nom;this.lieu = lieu;

}

R. Grin JPA page 9

Exemple d’entité – une association

@OneToMany(mappedBy="dept")private Collection<Employe> employes = new ArrayList<Employe>();

public Collection<Employe> getEmployes() {return employes;

}public void addEmploye(Employe emp) {employes.add(emp);

}

L’association inverse dans la classe Employe

R. Grin JPA page 10

Fichiers de configuration XML

META-INF/persistence.xml situé dans le classpath contient les informations pour obtenir une connexion à la BDLes annotations peuvent être remplacées par des fichiers de configuration XMLLes fichiers XML l’emportent sur les annotations

R. Grin JPA page 11

persistence.xml<persistence version= "1.0"

xmlns="http://java.sun.com/xml/ns/persistence"><persistence-unit name="employes"

transaction-type="JTA"><provider>org…PersistenceProvider</provider><jta-data-source>jdbc/formation</jta-data-

source><properties>

<property name="eclipselink.ddl-generation" value="create-tables"/>

<property name="eclipselink.logging.level" value="FINE"/>

</properties></persistence-unit>

</persistence>R. Grin JPA page 12

Gestionnaire d’entités (EM)

Classe javax.persistence.EntityManager

Interlocuteur principal pour le développeurFournit les méthodes pour gérer les entités : les rendre persistantes, les supprimer de la BD, retrouver leurs valeurs dans la BD, etc.

Page 3: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

3

R. Grin JPA page 13

Contexte de persistance

La méthode persist(objet) rend persistant objet qui sera alors géré par le EMToute modification apportée à objet sera enregistrée dans la BD par le EM au moment du commitL’ensemble des entités gérées par un EM s’appelle un contexte de persistance (CP)Dans un CP il ne peut exister 2 entités différentes qui représentent des données identiques dans la BD

R. Grin JPA page 14

Exemple

EntityManagerFactory emf = Persistence.createEntityManagerFactory("employes");

EntityManager em = emf.createEntityManager();EntityTransaction tx = em.getTransaction();tx.begin();Dept dept = new Dept("Direction", "Nice");em.persist(dept);dept.setLieu("Paris");tx.commit();

enregistré dans la BD

R. Grin JPA page 15

Exemple – dans un EJB

@Statelesspublic class DeptFacade {

@PersistenceContext(unitName = "employes")private EntityManager em;

public void create(String nom, String lieu) {Dept dept = new Dept(nom, lieu);em.persist(dept);dept.setLieu("Paris");

}...

}

EM injecté par le container

Transaction démarréeau début de la méthode

et fermée à la fin

R. Grin JPA page 16

Exemple (suite)String queryString =

"SELECT e FROM Employe e " + " WHERE e.poste = :poste";

Query q = em.createQuery(queryString);q.setParameter("poste", "INGENIEUR");List<Employe> liste = q.getResultList();for (Employe e : liste) {

System.out.println(e.getNom());} em.close();emf.close();

Les employés récupérés sontajoutés au contexte de persistance

Que va-t-il se passer si on en modifie un ?

R. Grin JPA page 17

Exemple (suite) – dans un EJBString queryString =

"SELECT e FROM Employe e " + " WHERE e.poste = :poste";

Query q = em.createQuery(queryString);q.setParameter("poste", "INGENIEUR");List<Employe> liste = q.getResultList();for (Employe e : liste) {

System.out.println(e.getNom());} Plus besoin de fermer l’EM et sa fabrique

R. Grin JPA page 18

Entités

Page 4: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

4

R. Grin JPA page 19

Conditions pour une classe entité

Doit avoir un constructeur sans paramètre protected ou publicDoit posséder un attribut qui représente la clé primaire dans la BDNe doit pas être finalAucune méthode ou champ persistant ne doit être final

R. Grin JPA page 20

Convention de nommage JavaBean

Un JavaBean possède des propriétésUne propriété nommée « prop » est représentée par 2 méthodes pour lire et écrire sa valeur : n getProp() (ou isProp() si la propriété

est de type boolean) n setProp(TypeDeProp prop)

R. Grin JPA page 21

Types d’accès à une valeur persistanteL’état persistant d’un objet est constitué par les valeurs de ses attributsLe fournisseur de persistance peut accéder à la valeur d’un attribut de 2 façonsn soit en accédant directement à la variable

d’instance ; c’est l’accès « par champ »n soit en passant par les accesseurs (getter

ou setter) ; c’est l’accès « par propriété »Si l’accès se fait par propriété, les getter et setter doivent être protected ou public

R. Grin JPA page 22

Type d’accès par défautLe type d’accès par défaut est défini par la position des annotations dans la classe entitéIl doit être le même pour toute une hiérarchie d’héritageJPA 2.0 permet de changer le type d’accès pour une classe ou un attribut en ajoutant une annotation Access : @Access(PROPERTY) ou @Access(FIELD)

R. Grin JPA page 23

Exemple

Accès par champ :@Idprivate int id;

Accès par propriété :@Idpublic int getId() {

…}

R. Grin JPA page 24

Quel type d’accès choisir ?L’accès par propriété oblige à ajouter des getters et des setters pour tous les attributsIl est conseillé de choisir plutôt l’accès par champ

Page 5: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

5

R. Grin JPA page 25

Attributs persistants

Par défaut, tous les attributs d’une entité sont persistantsException : attribut avec un champ transient ou annoté par @Transient

R. Grin JPA page 26

Types persistants

Un attribut peut être d’un des types suivants :n type « basic »n type « Embeddable »n collection d’éléments de type « basic » ou

EmbeddablePour représenter une association entre entités :n entitén collection d’entités

R. Grin JPA page 27

Types « basic »

Types primitifs (int, double,…)String, BigInteger, BigDecimal, enveloppes de type primitifs (Integer,…)Date, Calendar, Time, TimestampEnumérationsTableaux de byte, Byte, char, CharacterPlus généralement Serializable(sauvegardé comme un tout dans la base)

R. Grin JPA page 28

Cycle de vie d’une instance d’entité

L’instance peut êtren nouvelle : créée mais pas gérée par un EMn gérée par un EM ; elle a une identité dans la

BD (méthode persist, ou instance récupérée dans la BD par une requête)

n détachée : a une identité dans la BD mais n’est plus gérée par un EM

n supprimée : gérée par un EM ; données supprimées dans la BD au commit (méthode remove)

R. Grin JPA page 29

Les tables de la base de données

Dans les cas simples, une classe ↔ une table n nom de la table = nom de la classen noms des colonnes = noms des attributs

Par exemple, la classe Departementcorrespond à la table Departement avec les colonnes id, nom, lieu

R. Grin JPA page 30

Configuration « par exception »

Mapping « JPA » par défaut pour les classes entitésAjouter des annotations seulement si les valeurs par défaut ne conviennent pasPar exemple, @Entity suppose que la table a le même nom que la classeSi on veut lui donner un autre nom on ajoute :@Table(name = "autre_nom")

Page 6: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

6

R. Grin JPA page 31

Classe Embeddable

Classe persistante dont les données n n’ont pas d’identité dans la BD n sont insérées dans une table associée à

une entité

R. Grin JPA page 32

Exemple@Embeddablepublic class Adresse {private int numero;private String rue;private String ville;. . .

}@Entitypublic class Employe {@Embeddedprivate Adresse adresse;...

}

R. Grin JPA page 33

Gestionnaire d’entités(Entity Manager), EM

R. Grin JPA page 34

Principe de base

La persistance des entités n’est pas transparenteUne instance d’entité ne devient persistante que lorsque l’application appelle la méthode appropriée du gestionnaire d’entités(persist ou merge)

R. Grin JPA page 35

Unité de persistance

Configuration nommée qui contient les informations nécessaires à l’utilisation d’une base de donnéesDéfinie dans un fichier META-INF/persistence.xmlsitué dans le classpath

R. Grin JPA page 36

Cycle de vie d’un EM dans Java SE

En dehors d’un serveur d’application, c’est l’application qui décide de la durée de vie d’un EMCréation d’un EM :EntityManagerFactory emf = Persistence.createEntityManagerFactory("employes");

EntityManager em =emf.createEntityManager();

Fermeture du EM (plus possible de l’utiliser ensuite) :em.close();

Page 7: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

7

R. Grin JPA page 37

Types de EMdans un serveur d’application

EM géré par le container (le cas le plus fréquent)n délimité par les transactions

(TRANSACTION)n peut survivre à une fin de transaction

(EXTENDED) ; nécessite un bean session avec état (stateful)

EM géré par l’application (comme en dehors d’un serveur d’applications) ; pas délimité par les transactions

R. Grin JPA page 38

Exemple – géré par le container

@Statelesspublic class DeptFacade {

@PersistenceContext(unitName = "employes")private EntityManager em;

public void create(String nom, String lieu) {Dept dept = new Dept(nom, lieu);em.persist(dept);dept.setLieu("Paris");

}...

}

EM injecté par le container

Ne dure que le tempsde la transaction

R. Grin JPA page 39

Exemple – géré par l’application@Statelesspublic class DeptFacade {

@PersistenceUnit(unitName = "employes")private EntityManagerFactory emf;

public void create(String nom, String lieu) {EntityManager em = emf.createEntityManager();Dept dept = new Dept(nom, lieu);em.persist(dept);dept.setLieu("Paris");em.close();

}...

}

Fabrique d’EM injectéepar le container

Choix du type d’EM

Bien plus simple de le faire gérer par le container (propagation des transactions, pas besoin de le fermer)Un EM géré par l’application ne doit être utilisé que lorsque c’est nécessaire ; par exemple, avec une servlet car une fabrique d’EM est thread-safe, ce que n’est pas un EMEviter de mélanger les 2 types de gestion

R. Grin JPA page 40

R. Grin JPA page 41

Méthodes de EntityManagervoid persist(Object entité)<T> T merge(T entité)void remove(Object entité)<T> T find(Class<T> classeEntité, Object cléPrimaire)void flush()void setFlushMode(FlushModeTypeflushMode)

R. Grin JPA page 42

Méthodes de EntityManagervoid lock(Object entité, LockModeType lockMode)void refresh(Object entité)void clear()boolean contains(Object entité)void close()

Page 8: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

8

R. Grin JPA page 43

Méthodes de EntityManagerQuery createQuery(String requête)Query createNamedQuery(String nom)Query createNativeQuery(String requête)Query createNativeQuery(String requête, Class classeRésultat)

R. Grin JPA page 44

flush

Enregistre dans la BD les modifications effectuées sur les entités d’un contexte de persistanceLe EM lance les commandes SQL adaptées pour modifier la BD (INSERT, UPDATE ou DELETE)Automatiquement effectué à chaque commit

R. Grin JPA page 45

persist(entité)

entité devient une entité géréeL’état de entité sera sauvegardé dans la BD au prochain flush ou commitAucune autre instruction ne sera nécessaire pour que les modifications effectuées ensuite sur entité soient enregistrées au moment du commit

R. Grin JPA page 46

refresh(entité)

Les données de la BD sont copiées dans l’entitéPeut être utile pour les transactions longues

R. Grin JPA page 47

Contexte de persistance - cache

Joue le rôle de cache pour les accès à la BDUn find ou un query ramène les données du cacheBénéfice : meilleures performancesAttention : les données du cache ne tiennent pas compte des modifications effectuées sans passer par le EMPeut poser des problèmes ; un refresh peut alors être la solution

R. Grin JPA page 48

Entité détachée

Une entité gérée par un EM peut être détachée de son contexte de persistance (par exemple si le EM est fermé ou l’entité envoyée « au loin »)Cette entité détachée peut être modifiéePour que ces modifications soient enregistrées dans la BD, il est nécessaire de rattacher l’entité à un EM par la méthode merge (et de lancer ensuite un commit)

Page 9: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

9

R. Grin JPA page 49

merge(a)

Attention, la méthode merge n’attache pas aElle retourne une entité gérée qui a la même identité dans la BD que a, mais ça n’est pas le même objet (sauf si l’objet était déjà géré)Après un merge, l’application devra donc ne plus utiliser cet objet ; il faut donc écrire ce type de code :a = em.merge(a);

merge – une erreur à ne pas faire

em.merge(dept);dept.addEmploye(emp);em.commit();

L’ajout du nouvel employé ne sera pas enregistré dans la base car l’objet référencé par dept n’est pas géré ; le bon code :dept = em.merge(dept);dept.addEmploye(emp);em.commit();

R. Grin JPA page 50

Quel est le problème ?

2 types de contexte de persistance

Avec Java EE, le contexte de persistance est le plus souvent limité à une seule transactionIl peut aussi, comme pour Java SE, être « étendu », c’est-à-dire qu’il peut survivre à la fin de la transaction et donc être utilisé par plusieurs transactions ; en ce cas, l’association entre un CP et plusieurs EM est plus complexe qu’avec Java SE où il y a une bijection entre les CP et les EM

R. Grin JPA page 51 R. Grin JPA page 52

CP limité à une transaction

@Statelesspublic class DeptFacade {

@PersistenceContext(unitName = "employes")private EntityManager em;

public void create(String nom, String lieu) {Dept dept = new Dept(nom, lieu);em.persist(dept);dept.setLieu("Paris");

}...

}

R. Grin JPA page 53

CP étendu

Il est possible de faire durer un contexte de persistance pendant plusieurs transactions en injectant un EM qui a un contexte de persistance étendu :@PersistenceContext(unitName="Xxxxx"type=PersistenceContextType=EXTENDED)

EntityManager em;

Ce type de EM n’est disponible que dans un bean session avec état (stateful) ; il n’est pas disponible dans un bean session sans état (stateless)

R. Grin JPA page 54

Identité des entités

Page 10: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

10

R. Grin JPA page 55

Clé primaire

Une entité doit avoir un attribut, annoté @Id, qui correspond à la clé primaire dans la table associéeLa valeur de cet attribut ne doit jamais être modifiée dès que l’entité représente des données de la base

R. Grin JPA page 56

Type de la clé primaire

Type primitif JavaClasse qui enveloppe un type primitifjava.lang.Stringjava.util.Datejava.sql.Date

R. Grin JPA page 57

Génération automatique de clé

Pour les clés de type nombre entierL’annotation @GeneratedValue indique que la clé primaire sera générée par le SGBDCette annotation peut avoir un attribut strategy qui indique comment la clé sera générée

R. Grin JPA page 58

Type de génération

Énumération GenerationType ; les valeurs :AUTO : choisi par le fournisseur de persistance, selon le SGBD (séquence, table,…) ; valeur par défautSEQUENCE : séquenceIDENTITY : colonne de type IDENTITYTABLE : table qui contient la prochaine valeur de l’identificateur

R. Grin JPA page 59

Exemple

@Id@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "EMP_SEQ")

private long id;

R. Grin JPA page 60

Clé composite

Pas recommandé, mais une clé primaire peut être composée de plusieurs colonnesPeut arriver quand la BD existe déjà, en particulier quand la classe correspond à une table association (association M:N)2 possibilités : n @EmbeddedId et @Embeddablen @IdClass

Page 11: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

11

R. Grin JPA page 61

Classe pour la clé composite

Dans les 2 cas la clé composite doit être représentée par une classe à partCette classe doitn être publicn posséder un constructeur sans paramètren être sérialisablen redéfinir equals et hashcode

R. Grin JPA page 62

Exemple avec @EmbeddedId@Entitypublic class Employe {@EmbeddedIdprivate EmployePK employePK;...

}

@Embeddablepublic class EmployePK {private String nom;private Date dateNaissance;...

}

R. Grin JPA page 63

Associations

R. Grin JPA page 64

Association bidirectionnelle

Le développeur est responsable de la gestion correcte des 2 bouts de l’associationPar exemple, si un employé change de département, les collections des employés des départements concernés doivent être modifiées

R. Grin JPA page 65

Méthode de gestion de l’associationPour faciliter la gestion des 2 bouts, il est commode d’ajouter une méthode qui effectue tout le travailEn particulier, dans les associations 1-N, le bout « 1 » peut comporter ce genre de méthode :public void ajouterEmploye(Employe e) {Departement d = e.getDept();if (d != null)d.employes.remove(e);

this.employes.add(e);employe.setDept(this);

}

Dans quelle classeest ce code ?

R. Grin JPA page 66

Bout propriétaire

Un des 2 bouts est dit propriétaire de l’association ; celui qui contient la clé étrangèrePour les associations 1 – N, c’est le bout … ?NL’autre bout contient l’attribut mappedBy qui donne le nom de l’attribut dans le bout propriétaire

Page 12: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

12

R. Grin JPA page 67

Exemple

Dans la classe Employe :@ManyToOneprivate Departement departement;

Dans la classe Departement : @OneToMany(mappedBy = "departement")private Collection<Employe> employes;

Quel est le bout propriétaire ?

Dans quelle table sera la clé étrangère ?

Nom de la colonne clé étrangère : DEPARTEMENT_ID

Classe Employe

Table EMPLOYE

Valeurs par défaut

Si une valeur par défaut ne convient pas, ajouter une annotation dans le bout propriétairePar exemple, pour indiquer le nom de la colonne clé étrangère :@ManyToOne@JoinColumn(name="DEPT")private Departement departement;

R. Grin JPA page 68

R. Grin JPA page 69

Association M:N

Traduite par 1 ou 2 collections annotées par @ManyToMany

Pourquoi « 1 ou 2 » ?On peut choisir le bout propriétaire

R. Grin JPA page 70

Exemple

@ManyToManyprivate Collection<Projet> projets;

@ManyToMany(mappedBy = "projets")private Collection<Employe> employes;

Quel est le bout propriétaire ?

Dans quelle table sera la clé étrangère ?

Dans quelle classe ?

Dans quelle classe ?

@JoinTable

Si les valeurs par défaut ne conviennent pas, des informations sur la table association peuvent être données dans le bout propriétaire de l’association (annotation @JoinTable)

R. Grin JPA page 71 R. Grin JPA page 72

Exemple (classe Employe)

@ManyToMany@JoinTable(name = "EMP_PROJET",joinColumns = @JoinColumn(name="matr"),inverseJoinColumns=@JoinColumn(name="code_Projet")

)private Collection<Projet> projets;

Page 13: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

13

R. Grin JPA page 73

Exemple (classe Employe)

@ManyToMany@JoinTable(name = "EMP_PROJET",joinColumns = @JoinColumn(name="matr"),inverseJoinColumns=@JoinColumn(name="code_Projet")

)private Collection<Projet> projets;

Nom de la table association

R. Grin JPA page 74

Exemple (classe Employe)

@ManyToMany@JoinTable(name = "EMP_PROJET",joinColumns = @JoinColumn(name="matr"),inverseJoinColumns=@JoinColumn(name="code_Projet")

)private Collection<Projet> projets;

Colonne de la table association qui

référence le bout propriétaire

R. Grin JPA page 75

Exemple (classe Employe)

@ManyToMany@JoinTable(name = "EMP_PROJET",joinColumns = @JoinColumn(name="matr"),inverseJoinColumns=@JoinColumn(name="code_Projet")

)private Collection<Projet> projets;

Colonne de la table

association qui

référence l’autre bout

R. Grin JPA page 76

Association M:N avec information portée par l’association

Exemple :Association entre les employés et les projets ; un employé a une fonction dans chaque projet auquel il participe

R. Grin JPA page 77

Classe association

Association M:N traduite par une classe associationChaque classe qui participe à l’association peut avoir une collection d’objets de la classe association (suivant directionnalité)2 possibilités pour la classe association : n un attribut identificateur (@Id) unique (le

plus simple)n un attribut identificateur par classe

participant à l’associationR. Grin JPA page 78

Code classe association (début)

@Entitypublic class Participation {@Id @GeneratedValueprivate int id;@ManyToOneprivate Employe employe;@ManyToOneprivate Projet projet;private String fonction;

Page 14: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

14

R. Grin JPA page 79

Code classe association (fin)public Participation() { }

public Participation(Employe employe, Projet projet, String fonction) {

this.employe = employe; this.projet = projet; this.fonction = fonction;

}// Accesseurs pour employe et projet...

R. Grin JPA page 80

Persistance des objets associésLorsqu’un objet obj est rendu persistant, il est naturel que les objets référencés par objdeviennent eux-aussi persistantsSinon, une partie de l’état de l’objet ne serait pas persistanteCe concept s’appelle la « persistance par transitivité » (reachability)Si c’est fait automatiquement, quand un objet A est rendu persistant, le service de persistance doit parcourir tous les objets référencés par A, et ceci récursivement

R. Grin JPA page 81

Pas de persistance par transitivité automatique avec JPA

Par défaut, JPA n’effectue pas automatiquement la persistance par transitivitéRendre persistant un département ne suffit pas à rendre persistants ses employésLa cohérence des données de la BD repose donc sur le code de l’application

R. Grin JPA page 82

Cohérence des données

Soit une classe Departement qui contient une collection d’EmployeSi un département est rendu persistant et si un des employés du département est non persistant, une IllegalStateExceptionest lancée au moment du commitL’attribut cascade des associations peut simplifier le code

R. Grin JPA page 83

Cascade

Les opérations persist, remove, refresh, merge peuvent être transmises par transitivité à l’autre bout d’une associationExemple :@OneToMany(cascade = { CascadeType.PERSIST,

CascadeType.MERGE }, mappedBy = "client")

private Collection<Facture> factures;

Dans quelle classe est ce code ? Qu’indique l’attribut cascade ?

R. Grin JPA page 84

Récupération des entités associées

Lorsqu’une entité est récupérée depuis la BD (Query ou find), est-ce que les entités associées sont aussi récupérées ?Si elles sont récupérées, est-ce que les entités associées à ces entités doivent elles aussi être récupérées ?Le risque est de récupérer un très grand nombre d’entités inutiles

Page 15: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

15

R. Grin JPA page 85

EAGER ou LAZY

JPA laisse le choix de récupérer ou non immédiatement les entités associéesMode EAGER : les données associées sont récupérées immédiatement Mode LAZY : les données associées ne sont récupérées que lorsque c’est vraiment nécessaire (lazy loading)

R. Grin JPA page 86

Type de récupération par défaut des entités associées

Mode EAGER pour les associations OneToOneet ManyToOneMode LAZY pour les associations OneToManyet ManyToMany

Vous voyez une raison pour ce choix ?

R. Grin JPA page 87

Indiquer le type de récupération des entités associées

L’attribut fetch permet de modifier le comportement par défaut@OneToMany(mappedBy = "departement",

fetch = FetchType.EAGER)private Collection<Employe> employes;

Architecture commune d’une application

Un bean session charge les entitésLes entités sont ensuite utilisées pour afficher des informations dans une page WebExemple : un département est récupéré dans la base et affiché sur la page du clientLes informations affichées peuvent provenir d’une entité associéeExemple : les noms des employés du département

R. Grin JPA page 88

Problèmes liés au lazy loading

Si les entités sont détachées et les informations associées ne sont chargées qu’en mode « lazy », il n’est plus possible de de récupérer ces informations associéesIl existe plusieurs stratégies pour pallier ce problème

R. Grin JPA page 89

Stratégies pour le lazy loading (1/2)

Le plus simple est de récupérer les informations associées avant le détachement (fetch join ou appel d’une méthode des entités associées) et l’envoi au clientOn peut aussi ne pas utiliser les entités mais plutôt exactement les informations à afficher (enregistrées dans des propriétés non persistantes ou dans des objets de type DTO) ; on récupère ces informations avec une requête ad-hoc

R. Grin JPA page 90

Page 16: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

16

Stratégies pour le lazy loading (2/2)

Les autres solutions s’arrangent pour ne fermer le contexte de persistance qu’après l’affichage des informations au client ; les entités ne sont alors plus détachées quand on a besoin de charger les informations associées

R. Grin JPA page 91 R. Grin JPA page 92

Héritage

R. Grin JPA page 93

Stratégies2 stratégies pour la traduction de l’héritage :n une seule table pour une hiérarchie

d’héritage (SINGLE_TABLE) ; par défautn une table par classe ; les tables sont jointes

pour reconstituer les données (JOINED)La stratégie « une table distincte par classe concrète » est optionnelle (TABLE_PER_CLASS)

R. Grin JPA page 94

Exemple « 1 table par hiérarchie »

@Entity@Inheritance(strategy =InheritanceType.SINGLE_TABLE)

public abstract class Personne {...}

@Entity@DiscriminatorValue("E")public class Employe extends Personne {...

}

« Employe » par défaut

Dans la classe racine de la hiérarchie ; optionnel

R. Grin JPA page 95

Table

La table a le nom de la table associée à la classe racine de la hiérarchie d’héritageElle doit comporter une colonne discriminatrice

R. Grin JPA page 96

Une table par classe

La table qui correspond à la classe racine de la hiérarchie d’héritage doit comporter une colonne discriminatrice

Page 17: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

17

R. Grin JPA page 97

Exemple

@Entity@Inheritance(strategy =

InheritanceType.JOINED)public abstract class Personne {...}

@Entity@DiscriminatorValue("E")public class Employe extends Personne {...

}

R. Grin JPA page 98

Classe mère persistante

Une entité peut avoir une classe mère dont l’état est persistant, sans que cette classe mère ne soit une entitéL’état de la classe mère sera enregistré dans la même table que les entités fillesEn ce cas, la classe mère doit être annotée par @MappedSuperclassUne classe entité peut aussi hériter d’une classe mère dont l’état n’est pas persistant

R. Grin JPA page 99

Requêtes – JPQLJava Persistence Query Language

R. Grin JPA page 100

IMPORTANT

Cette section concerne les entités retrouvées en interrogeant la base de donnéesToutes ces entités sont automatiquement gérées par le gestionnaire d’entitésLes modifications apportées à ces entités seront enregistrées au prochain commit

R. Grin JPA page 101

Chercher par identitéfind (de EntityManager) retrouve une entité en donnant son identificateur dans la BD2 paramètres de type n Class<T> pour le type de l’entité

recherchéen Object pour la clé primaire

Exemple :Departement dept =em.find(Departement.class, 10);

Il est possible de rechercher des données sur des critères plus complexes que la simple identité

R. Grin JPA page 102

Page 18: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

18

R. Grin JPA page 103

Étapes pour récupérer des données

1. Décrire ce qui est recherché (langage JPQL)2. Créer une instance de type Query3. Initialiser la requête (paramètres, pagination)4. Lancer l’exécution de la requête

R. Grin JPA page 104

Exemple

String s = "select e from Employe as e"; Query query = em.createQuery(s); List<Employe> listeEmployes = (List<Employe>)query.getResultList();

R. Grin JPA page 105

Exemple plus complexeString q = "select e from Employe as e " + "where e.departement.numero = :numero"; Query query = em.createQuery(q); query.setParameter("numero", 10);query.setMaxResults(30);for (int i = 0; i < 5; i++) {query.setFirstResult(30 * i);List<Employe> listeEmployes = (List<Employe>)query.getResultList();

... // Affichage page numéro i + 1}

R. Grin JPA page 106

Langage JPQL

Java Persistence Query Language décrit ce qui est recherché en utilisant le modèle objet (pas le modèle relationnel)Les seules classes qui peuvent être utilisées sont les entités et les Embeddable

R. Grin JPA page 107

Exemples de requêtes

select e from Employe eselect e.nom, e.salaire from Employe eselect e from Employe e where e.departement.nom = 'Direction'select d.nom, avg(e.salaire) from Departement d join d.employes e group by d.nomhaving count(d.nom) > 5

Alias de classe obligatoire

R. Grin JPA page 108

Obtenir le résultat de la requête

Résultat = une seule valeur ou entité : Object getSingleResult()

Résultat = plusieurs valeurs ou entités : List getResultList()

Page 19: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

19

R. Grin JPA page 109

Type d’un élément du résultat

Le type d’un élément du résultat est n Object si la clause select ne comporte

qu’une seule expressionn Object[] sinon

R. Grin JPA page 110

Exemple

texte = "select e.nom, e.salaire " + " from Employe as e";

query = em.createQuery(texte);List<Object[]> liste = (List<Object[]>)query.getResultList();

for (Object[] info : liste) {System.out.println(info[0] + " gagne "

+ info[1]);}

R. Grin JPA page 111

Interface Query

Instance obtenue par les méthodes createQuery, createNativeQuery ou createNamedQuery de EntityManager

R. Grin JPA page 112

Types de requête

Requête dynamique : texte donné en paramètre de createQueryRequête native (ou SQL) particulière à un SGBD : requête SQL avec tables et colonnes (pas classes et attributs) ; createNativeQuery

Requête nommée : texte statique donné dans une annotation d’une entité ; le nom est passé en paramètre de createNamedQuery ; peut être écrite en JPQL ou en SQL (native)

R. Grin JPA page 113

Exemple de requête nommée@Entity@NamedQuery (name = "employe.findNomsEmpsDept",query = "select e.nom from Employe as e where upper(e.departement.nom) = :nomDept"

)public class Employe extends Personne {...

Query q = em.createNamedQuery("findNomsEmpsDept");

R. Grin JPA page 114

Paramètre des requêtes

Désigné par son numéro (?n) ou par son nom (:nom)Valeur donnée par une méthode setParameter

Page 20: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

20

R. Grin JPA page 115

Exemples

Query query = em.createQuery("select e from Employe as e "+ "where e.nom = ?1");

query.setParameter(1, "Dupond");Query query = em.createQuery("select e from Employe as e "+ "where e.nom = :nom");

query.setParameter("nom", "Dupond");

R. Grin JPA page 116

Clauses d’un select

selectfromwheregroup byhavingorder by

R. Grin JPA page 117

Polymorphisme dans les requêtes

Les requêtes sont polymorphes : un nom de classe dans la clause from désigne cette classe et toutes les sous-classesExemple :select count(a) from Article as a

On peut restreindre à un type donné :select a from Article a where type(a) in (Stylo, Lot)

R. Grin JPA page 118

Clauses where et having

Peuvent comporter :n [NOT] LIKE, [NOT] BETWEEN, [NOT] INn AND, OR, NOTn [NOT] EXISTSn ALL, SOME/ANYn IS [NOT] EMPTY, [NOT] MEMBER OF

Pour les collections

R. Grin JPA page 119

Sous-requête

where et having peuvent contenir des sous-requêtes (et peuvent être synchronisées){ALL | ANY | SOME} (sous-requête) fonctionne comme dans SQLExemple :select e from Employe ewhere e.salaire >= ALL (select e2.salaire from Employe e2where e2.departement =

e.departement)

R. Grin JPA page 120

Navigation

Il est possible de suivre le chemin correspondant à une association avec la notation « pointée »

Page 21: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

21

R. Grin JPA page 121

Exemple

e alias pour Employe, n « e.departement » désigne le

département d’un employén « e.projets » désigne les projets

auxquels participe un employéselect e.nomfrom Employe as ewhere e.departement.nom = 'Qualité'

R. Grin JPA page 122

Règles pour les expressions de chemin

Une navigation peut être chaînée à une navigation précédente si la navigation précédente ne donne qu’une seule entité(OneToOne ou ManyToOne)

R. Grin JPA page 123

Exemple

select e.nom,e.departement.nom,e.superieur.departement.nom

from Employe e

R. Grin JPA page 124

Contre-exemple

« d.employes.nom » est interdit car d.employes est une collectionPour avoir les noms des employés d’un département, il faut utiliser une jointure :select e.nomfrom Departement d

join d.employes ewhere d.nom = 'Direction'

R. Grin JPA page 125

Jointure

Interne (jointure standard join), Externe (left outer join) Avec récupération de données en mémoire (join fetch) ; pour éviter le problème des « N +1 selects »

R. Grin JPA page 126

Exemples

select e.nom, particips.projet.nomfrom Employe e

join e.participations participsselect e.nom, d.nomfrom Employe e, Departement dwhere d = e.departement

Page 22: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

22

R. Grin JPA page 127

join fetch

Évite le problème des « N + 1 selects »select e from Employe as e

join fetch e.participationsLes participations placées à droite de join fetchsont créées en même temps que les employés (mais pas renvoyées par le select)

L’instructionemploye.getParticipations()ne nécessitera pas d’accès à la base

R. Grin JPA page 128

Fonctions

Pour les chaînes de caractères : concat, substring, trim, lower, upper, length, locateArithmétique : abs, sqrt, mod, sizeTemporelles : current_date, current_time, current_timestampFonctions de regroupement : count, max, min, avg

case (semblable CASE de SQL)

API « criteria »Introduite par JPA 2.0Tout ce qui peut être fait avec JPQL peut l’être avec cette APILes requêtes JPQL sont des String qui peuvent contenir des erreurs (par exemple le nom d’une classe qui n’existe pas)L’avantage de l’API « critères » est que les requêtes peuvent être vérifiées à la compilationL’inconvénient est que le code est un peu plus complexe à écrire, et sans doute moins lisible

R. Grin JPA page 129 R. Grin JPA page 130

Opération de modification en volume

R. Grin JPA page 131

Utilité

Augmenter les 10000 employés de 5%Mauvaise solution : n Créer toutes les entités « Employe » en lisant les

données dans la basen Modifier le salaire de chaque entitén Enregistrer ces modifications dans la base

JPQL permet de modifier les données de la base directement, sans créer les entités correspondantes

R. Grin JPA page 132

Exempleem.getTransaction().begin();String ordre =

"update Employe e " +" set e.salaire = e.salaire * 1.05";

Query q = em.createQuery(ordre);int nbEntitesModif = q.executeUpdate();em.getTransaction().commit();

Page 23: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

23

R. Grin JPA page 133

Exceptions

R. Grin JPA page 134

Exceptions de JPA

JPA n’utilise que des exceptions non contrôléesElles héritent de PersistenceException

R. Grin JPA page 135

Types d’exceptionEntityNotFoundExceptionEntityExistsExceptionTransactionRequiredExceptionRollbackExceptionOptimisticLockExceptionPessimisticLockException* LockTimeoutException* NonUniqueResultException* NoResultException

* : ne marquent pas la transaction pour un rollbackR. Grin JPA page 136

Transaction

R. Grin JPA page 137

EntityTransaction

En dehors d’un serveur d’applications, une application utilise l’interface javax.persistence.EntityTransactionpour travailler avec une transaction (transaction locale, non JTA)

R. Grin JPA page 138

Exemple

EntityManager em;...try {em.getTransaction().begin()...em.getTransaction().commit();

}finally {em.close();

}

Page 24: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

24

R. Grin JPA page 139

Modifications et commit

Les modifications effectuées sur les entités gérées sont enregistrées dans la base au moment d’un commitLes modifications sont enregistrées dans la base, même si elles ont été effectuées avant le début de la transaction (avant le tx.begin())

R. Grin JPA page 140

Rollback (1)

En cas de rollback,n rollback dans la base de donnéesn le contexte de persistance est vidé ; toutes

les entités deviennent détachées

R. Grin JPA page 141

Rollback (2)

Les instances d’entités Java gardent les valeurs qu’elles avaient au moment du rollbackMais ces valeurs sont le plus souvent faussesLe plus souvent il faut donc relancer des requêtes pour récupérer des entités avec des valeurs correctes

Transactions dans un serveur d’application

Il est fortement conseillé d’utiliser les transactions gérées par le container et définies par annotations ou dans un fichier XML de configurationPour des cas particuliers le développeur peut gérer les transactions explicitement avec les interfaces EntityTransaction ou javax.transaction.UserTransaction(transaction JTA)

R. Grin JPA page 142

R. Grin JPA page 143

UserTransaction

public interface UserTransaction {public void begin();public void commit();public void rollback();public void setRollbackOnly();public int getStatus();public void setTransactionTimeout(intsecondes);

}Une instance de UserTransactionpeut être injecté dans du codepar l’annotation @Resource

Les transactions sont étudiées en détails dans une autre partie du coursVoici des informations générales sur les transactions, en liaison avec les contextes de persistance

R. Grin JPA page 144

Page 25: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

25

R. Grin JPA page 145

Un principe

Pour que tout se passe bien, tous les appels de méthodes des EM durant une même transaction doivent utiliser le même contexte de persistanceSinon, des modifications effectuées sur des entités durant la transaction risquent d’être perdues par la suite dans la transactionJPA facilite l'application de ce principe (voir transparent suivant)

R. Grin JPA page 146

Modèle de conception dans Java EELa configuration par défaut correspond à « une transaction par requête de l’utilisateur » : n la transaction démarre au début du

traitement d’une requêten et elle se termine à la fin du traitement

Pour faciliter l’utilisation de ce modèle, le contexte de persistance peut se propager aux méthodes appelées durant toute la durée d’une transaction (détaillé plus loin)

R. Grin JPA page 147

Autre modèle de conception

Avec un bean session avec état (stateful) il est possible d’utiliser un même contexte de persistance étendu pour plusieurs transactions JTALe modèle de conception correspond à des traitements « conversationnels » qui peuvent couvrir plusieurs requêtes de l’utilisateur, sans bloquer toutes les ressources pendant toute la conversation (bloquées juste le temps d’une transaction)

R. Grin JPA page 148

Propagation de contexte

Un contexte de persistance peut être propagé durant une transaction JTA s’il est utilisé par des EMs gérés par le containerCe contexte est alors utilisé à tour de rôle durant la transaction par les EMsCette propagation s’appelle une propagation de contexteQuand un EM reçoit un message, il vérifie s’il existe un contexte propagé ; si c’est le cas, il utilise celui-ci, sinon il en crée un nouveau

R. Grin JPA page 149

Avantage de la propagation

Les modifications non encore enregistrées dans la base (elles le seront seulement au commit de la transaction), mais enregistrées dans le contexte de persistance, sont disponibles durant toute la transaction, quel que soit l’emplacement du code placé dans la transaction

R. Grin JPA page 150

joinTransaction

Lorsqu’un EM est créé explicitement par l’application (il n’est pas géré par le container), 2 cas :n si une transaction JTA est déjà active, le

contexte du EM est synchronisé avec la transaction

n sinon, le contexte peut plus tard être manuellement synchronisé avec la transaction par la méthode joinTransaction() de EntityManager

Page 26: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

26

R. Grin JPA page 151

Concurrence

R. Grin JPA page 152

Exemple de problème de concurrence « BD »

Une entité est récupérée depuis la BD (par un find par exemple)L’entité est ensuite modifiée par l’application puis la transaction est validéeSi une autre transaction a modifié entre-temps les données de la BD correspondant à l’entité, il y aura un problème de mise à jour perdue

R. Grin JPA page 153

Gestion de la concurrence

Par défaut, les problèmes d’accès concurrents sont gérés avec une stratégie optimiste :n T1 lit une entiténUne autre transaction T2 modifie alors les

données de la BD correspondant à l’entitén T1 ne pourra valider une modification de

l’entité

R. Grin JPA page 154

@Version

Annote un attribut qui représente un numéro de version, incrémenté automatiquement par JPA à chaque modificationPour savoir si l’état d’une entité a été modifié entre 2 moments différentsCorrespond à une colonne de la base de donnéesNe doit jamais être modifié par l’applicationRequis pour la portabilité de la gestion de la concurrence par JPA

R. Grin JPA page 155

Exemple

@Versionprivate int version;

R. Grin JPA page 156

lock(A, mode)

Protège une entité contre les accès concurrents pour les cas où la protection offerte par défaut ne suffit pas

Page 27: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

27

R. Grin JPA page 157

Modes de blocage optimistes

Valeurs de l’énumération LockModeTypeOPTIMISTIC : si une autre transaction T2 a modifié l’entité A, rollback de la transaction T1

Quelle différence avec le mode de protection par défaut ?

R. Grin JPA page 158

Modes de blocage optimistes

Valeurs de l’énumération LockModeTypeOPTIMISTIC : si une autre transaction T2 a modifié l’entité A, rollback de la transaction T1OPTIMISTIC_FORCE_INCREMENT : en plus, incrémenter le numéro de version de l’entité bloquée, même si elle n’a pas été modifiéeIl est parfois intéressant de considérer que l’entité a été modifiée si des objets associés ont été modifiés

Blocage pessimistes

Ils empêchent les autres transactions de modifier les données bloquées

R. Grin JPA page 159 R. Grin JPA page 160

Modes de blocage pessimistes (1)

PESSIMISTIC_WRITE pour, en plus, empêcher les autres transactions de bloquer en mode PESSIMISTIC_READ ou PESSIMISTIC_WRITE (jusqu’à la fin de la transaction) ; correspond à un « select for update »PESSIMISTIC_READ pour empêcher les lectures non répétables de l’entité bloquée ; empêche les autres transactions de bloquer la même entité en mode PESSIMISTIC_WRITE

R. Grin JPA page 161

Modes de blocage pessimistes (2)

PESSIMISTIC_FORCE_INCREMENT pour, en plus de PESSIMISTIC_WRITE, incrémenter le numéro de version de l’entité bloquée, même si elle n’a pas été modifiée

R. Grin JPA page 162

Concurrence et entité détachéeUne entité est détachée de son EMElle est modifiéeQuand elle est rattachée à un EM, le EM vérifie au moment du commit que le numéro de version n’a pas changéSi le numéro a changé, une OptimisticLockException est levée

Page 28: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

28

R. Grin JPA page 163

FIN DU COURS SUR JPA

R. Grin JPA page 164

Compléments sur les transactionset les contextes de persistance

R. Grin JPA page 165

Définition

Association d’un contexte de persistance avec une transaction JTA : le contexte de persistance est lié à la transaction ; le contexte devient le contexte actif lié à la transactionCette association va permettre au container de retrouver un contexte de persistance en interrogeant la transaction, et donc de permettre la propagation de contexte

R. Grin JPA page 166

Conflit de contextesSauf exception (voir transparent suivant), la propagation de contexte ne fonctionne pas lors de l’appel d’une méthode d’un bean session avec état (stateful) depuis un autre beanEn effet, une bean session avec état ne peut travailler qu’avec un seul contexte et ne peut accepter de travailler avec un autre contexte propagéUne exception est levéeVoir la spécification JPA pour plus de détails

R. Grin JPA page 167

Héritage de contexte

L’héritage de contexte limite les possibilités de conflit de contexteUn bean avec état créé par un autre beanavec état hérite du contexte de ce bean si les 2 beans utilisent un contexte de persistance étenduAinsi des appels de méthodes pourront se faire entre les 2 beans sans collision de contexte

R. Grin JPA page 168

Synchronisation

Il est possible de synchroniser plusieurs contextes de persistance gérés par l’application avec une même transaction JTAMais un seul contexte géré par le containerpeut être synchronisé avec une transaction JTA

Page 29: Plan de cette partie JPA 2.0 Présentation de JPA (Java ...deptinfo.unice.fr/.../supports/5-jpa2-oral.pdf · JPA 2.0 (Java Persistence API) pour Java EE 6 Université de Nice - Sophia

29

R. Grin JPA page 169

Conversation longue (1)

L’utilisation d'un contexte étendu permet d’implémenter des conversations longues entre un client et un bean session avec étatIl n’est pas indispensable, et souvent néfaste, qu’une seule transaction longue couvre toute la conversation

R. Grin JPA page 170

Conversation longue (2)

On peut commencer par une transaction, valider la transaction, passer des données au client qui les modifie et ensuite reprendre une autre transaction pour terminer la conversationDès que la 2ème transaction démarre, toutes les modifications faites entre les 2 transactions sont prises en compte par cette 2ème

transaction (utilisation de merge)