Download - Persistance dans Java EE 6 : JPA2 et EJB 3.1
![Page 2: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/2.jpg)
Note importante
Ce cours couvre les besoins les plus importants, vous pourrez retrouver un cours très complet sur JPA2 et sur la persistence en java en général sur la page de Richard Grin http://deptinfo.unice.fr/~grin/mescours/minfo/modper
sobj/supports/index.html
Aussi, une bonne référence en ligne sur JPA2 http://www.objectdb.com/api/java/jpa, en particulier
la section JPA2 annotations
![Page 3: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/3.jpg)
Contexte
Java EE 6 propose ce qu’on appelle « un web profile » Un sous-ensemble de java EE pour le
développement d’application web simples La suite sera abordée en partie l’an prochain
Dans ce web profile on propose : Vue : JSP ou facelets/JSF2 Contrôleur web : Servlets ou web service Composant métier : EJB type session + managed
beans + classes java standard, Accès aux données dans une BD via JPA2/EJB
type entity
![Page 4: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/4.jpg)
Contexte
![Page 5: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/5.jpg)
Contexte
![Page 6: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/6.jpg)
Entity Bean, introducton
Un Entity Bean représente Des objets persistants stockés dans une base de
donnée, Des noms, des données Gestion via JPA2 + sessions beans
Dans ce chapitre on étudiera Le concept de persistance, Ce qu'est un entity bean, du point de vue du
programmeur, Les caractéristiques des entity beans, Les concepts de programmation des entity beans.
![Page 7: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/7.jpg)
La persistance par sérialisation
Sérialisation = sauvegarde de l'état d'un objet sous forme d'octets. Rappel : l'état d'un objet peut être quelque chose de très
compliqué. Etat d'un objet = ses attributs, y compris les atributs hérités. Si les attributs sont eux-même des instances d'une classe, il
faut sauvegarder aussi les attributs de ces instances, etc…
A partir d'un état sérialisé, on peut reconstruire l'objet
En java, au travers de l'interface java.io.Serializable, des méthodes de java.io.ObjectInputStream et java.io.ObjectOutputStream
![Page 8: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/8.jpg)
La persistance par sérialisation
Défauts nombreux…
Gestion des versions, maintenance…
Pas de requêtes complexes… Ex : on sérialize mille comptes bancaires. Comment
retrouver ceux qui ont un solde négatif ?
Solution : stocker les objets dans une base de donnée!
![Page 9: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/9.jpg)
La persistance par mapping objet/BD relationelle
On stocke l'état d'un objet dans une base de donnée.
Ex : la classe Personne possède deux attributs nom et prenom, on associe cette classe à une table qui possède deux colonnes : nom et prenom.
On décompose chaque objet en une suite de variables dont on stockera la valeur dans une ou plusieurs tables.
Permet des requêtes complexes.
![Page 10: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/10.jpg)
La persistance par mapping objet/BD relationelle
![Page 11: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/11.jpg)
La persistance par mapping objet/BD relationelle
Pas si simple… Détermination de l'état d'un objet parfois difficile,
tout un art… Il existe des produits pour nous y aider…
EclipseLink, TopLink (WebGain), Hibernate (JBoss), Aujourd'hui la plupart des gens font ça à la main
avec JDBC ou SQL/J. Mais SQL dur à tester/debugger… source de
![Page 12: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/12.jpg)
La persistance à l'aide d'une BD Objet
Les Base de données objet stockent directement des objets.
Plus de mapping !
Object Query Language (OQL) permet de manipuler les objets…
Relations entre les objets évidentes (plus de join…)
Bonnes performances mais mauvaise scalabilité.
![Page 13: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/13.jpg)
Le modèle de persistence JPA 2
JPA 2 propose un modèle standard de persistance à l’aide des Entity beans
Les outils qui assureront la persistance (Toplink, Hibernate, EclipseLink, etc.) sont intégrés au serveur d’application et devront être compatibles avec la norme JPA 2.
Java EE 6 repose à tous les niveaux sur de « l’injection de code » via des annotations de codeSouvent, on ne fera pas de « new », les variables
seront créées/initialisées par injection de code.
![Page 14: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/14.jpg)
Qu'est-ce qu'un Entity Bean
Ce sont des objets qui savent se mapper dans une base de donnée.
Ils utilisent un mécanisme de persistance (parmi ceux présentés)
Ils servent à représenter sous forme d'objets des données situées dans une base de donnée Le plus souvent un objet = une ou plusieurs ligne(s)
dans une ou plusieurs table(s)
![Page 15: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/15.jpg)
Qu'est-ce qu'un Entity Bean
Exemples Compte bancaire (No, solde), Employé, service, entreprises, livre, produit, Cours, élève, examen, note,
Mais au fait, pourquoi nous embêter à passer par des objets ? Plus facile à manipuler par programme, Vue plus compacte, on regroupe les données dans un objet. On peut associer des méthodes simples pour manipuler ces
données… On va gagner la couche middleware !
![Page 16: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/16.jpg)
Exemple avec un compte bancaire
On lit les informations d'un compte bancaire en mémoire, dans une instance d'un entity bean,
On manipule ces données, on les modifie en changeant les valeurs des attributs d'instance,
Les données seront mises à jour dans la base de données automatiquement !
Instance d'un entity bean = une vue en mémoire des données physiques
![Page 17: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/17.jpg)
Fichiers composant un entity bean
Schéma classique : La classe du bean se mappe dans une base de données. C’est une classe java « normale » (POJO) avec des attributs,
des accesseurs, des modifieurs, etc. On utilisera les méta-données ou « attributs de code » pour
indiquer le mapping, la clé primaire, etc. Clé primaire = un objet sérializable, unique pour chaque
instance. C'est la clé primaire au sens SQL. Note : on peut aussi utiliser un descripteur XML à la place
des annotations de code On manipulera les données de la BD à l’aide des EntityBeans
+ à l’aide d’un PERSISTENT MANAGER. Le PM s’occupera de tous les accès disque, du cache, etc.
Lui seul contrôle quand et comment on va accéder à la BD, c’est lui qui génère le SQL, etc.
![Page 18: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/18.jpg)
Exemple d’entity bean : un livre
@Entity public class Book { @Id @GeneratedValue private Long id; @Column(nullable = false) private String title; private Float price; @Column(length = 2000) private String description; private String isbn; private Integer nbOfPage; private Boolean illustrations; // Constructors, getters, setters }
![Page 19: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/19.jpg)
Exemple d’entity bean : un livre
@Entity public class Book { @Id @GeneratedValue private Long id; @Column(nullable = false) private String title; private Float price; @Column(length = 2000) private String description; private String isbn; private Integer nbOfPage; private Boolean illustrations
![Page 20: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/20.jpg)
Les annotations de code JPA 2
Remarques générales (suite) Nombreuses valeurs par défaut, par exemple une
classe entité Personne se mappera dans la table PERSONNE par défaut, un attribut « nom » sur la colonne NOM, etc.
Il existe de très nombreux attributs pour les annotations, ce cours présente les principaux, pour une étude détaillée, voir la spécification, un livre, ou le tutorial Java EE 6
Les règles de JDBC s’appliquent pour le mapping des types. String vers VARCHAR, Long vers BIGINT, Boolean vers SMALLINT, etc.
![Page 21: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/21.jpg)
Les annotations de code JPA 2
Remarques générales String vers VARCHAR(255) par défaut, Les règles peuvent changer d’un SGBD à l’autre,
par exemple String est mappé sur VARCHAR avec Derby, mais sur VARCHAR2 avec Oracle. Un Integer sur un INTEGER avec Derby mais sur un NUMBER avec Oracle. Etc.
Dans le cas des clés primaires auto-incrémentées, la manière dont elles sont gérées dépend du SGBD et de l’outil de mapping relationnel-objetSi on en change -> la structure des tables
change !
![Page 22: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/22.jpg)
Exemple d’insertion d’un livre
public class Main { public static void main(String[] args) { // On crée une instance de livre Book book = new Book(); book.setTitle("The Hitchhiker's Guide to the Galaxy"); book.setPrice(12.5F); book.setDescription("Science fiction comedy book"); … // On récupère un pointeur sur l’entity manager
// Remarque : dans une appli web, pas besoin de faire tout cela ! EntityManagerFactory emf = Persistence.createEntityManagerFactory("chapter02PU"); EntityManager em = emf.createEntityManager(); // On rend l’objet « persistant » dans la base (on l’insère) EntityTransaction tx = em.getTransaction(); tx.begin(); em.persist(book); tx.commit(); em.close(); emf.close(); }
![Page 23: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/23.jpg)
Client sous forme de session bean
Dans le cas où le client est un « session bean » du code peut être « injecté », Les transactions sont déclenchées par défaut,
@statelesspublic class UnSessionBean {
@PersistenceContext(unitName="EmployeeService")EntityManager em;
public Employee createEmployee(int id, String name, long salary, byte[] pic) { Employee emp = new Employee(id); emp.setName(name); … em.persist(emp); return emp; }
![Page 24: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/24.jpg)
Client sous forme de session bean
Dans le cas où le client est un « session bean » du code peut être « injecté », Les transactions sont déclenchées par défaut,
@statelesspublic class UnSessionBean {
@PersistenceContext(unitName="EmployeeService")EntityManager em;
public Employee createEmployee(int id, String name, long salary, byte[] pic) { Employee emp = new Employee(id); emp.setName(name); … em.persist(emp); return emp; }
![Page 25: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/25.jpg)
Client sous forme de session bean
@Stateless public class BookBean { @PersistenceContext(unitName = "chapter04PU") private EntityManager em; public void createBook() {
Book book = new Book(); book.setId(1234L); book.setTitle("The Hitchhiker's Guide to the Galaxy"); book.setPrice(12.5F); book.setDescription("Science fiction created by Douglas Adams."); book.setIsbn("1-84023-742-2"); book.setNbOfPage(354); book.setIllustrations(false); em.persist(book); // Récupère le livre dans la BD par sa clé primaire book = em.find(Book.class, 1234L); System.out.println(book); } }
![Page 26: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/26.jpg)
Remarques : à quoi correspond le session bean ?
On codera la partie « métier » Souvent on utilise un session bean pour la couche
« DAO » (avec des fonctions de création, recherche, modification et suppression d’entity beans)Exemple : GestionnaireUtilisateurs
On utilisera aussi des session beans pour implémenter des services compositesExemple : GestionnaireDeCommandes, qui
utilisera d’autres gestionnaires
![Page 27: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/27.jpg)
Autres annotations
@Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(name = "book_title", nullable = false, updatable = false) private String title; private Float price; @Column(length = 2000) private String description; private String isbn; @Column(name = "nb_of_page", nullable = false) private Integer nbOfPage; private Boolean illustrations; @Basic(fetch = FetchType.LAZY) @Lob private byte[] audioText; // Constructors, getters, setters }
![Page 28: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/28.jpg)
Autres annotations (suite)
@Column permet d’indiquer des préférences pour les colonnes Attributs possibles : name, unique, nullable, insertable,
updatable, table, length, precision, scale… @GeneratedValue
Indique la stratégie de génération automatique des clés primaires,
La valeur : GenerationType.auto est recommandée, Va ajouter une table de séquence
@Lob indique « large object » (pour un BLOB) Souvent utilisé avec @Basic(fetch = FetchType.LAZY)
pour indiquer qu’on ne chargera l’attribut que lorsqu’on fera un get dessus
![Page 29: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/29.jpg)
Autres annotations (suite)
Il existe de nombreuses autres annotations, Voir par exemple : JPA Reference
http://www.objectdb.com/api/java/jpa
Il se peut que les TPs en introduisent certaines.
Les curieux peuvent consulter la spécification java EE 6 ou le tutorial (ou un bon livre)
![Page 30: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/30.jpg)
Exemple de fichier persistence.xml
Ce fichier « configure » le persistence manager<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" mlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="IGift-ejbPU" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>jdbc/igift</jta-data-source>
<properties> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties>
</persistence-unit>
</persistence>
![Page 31: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/31.jpg)
Un exemple d’entity bean : un compte bancaire
•La classe = POJO,
•Sérializable,
•Un attribut = la clé primaire
•C’est tout !
![Page 32: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/32.jpg)
Client de l’entity bean précédent : un session bean (servant de façade/DAO)
•Ce session bean est stateless,
•Utilise un EntityManager,
•Sert à envoyer des requêtes JPQL,
•Méthode persist(entity) pour créer une nouvelle entrée (insert)
•Le reste passe par des appels de méthodes classiques de l’entity bean.
![Page 33: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/33.jpg)
Autre version : on garde dans le session bean la « mémoire » de l’entity bean
•Le session bean est stateful,
•Il garde la référence de l’entity bean,
•On a du « étendre » la portée du Persistence Manager
![Page 34: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/34.jpg)
Suite de l’exemple
•Dans getBalance() on n’utilise plus de find,
•On utilise les Exceptions
![Page 35: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/35.jpg)
Caractéristiques des entity beans
Survivent aux crashes du serveur, du SGBD
Ce sont des vues sur des données dans un SGBD
![Page 36: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/36.jpg)
Modifier les données sans passer par le bean
![Page 37: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/37.jpg)
Packager et déployer un Entity Bean
Les EB sont déployés dans des « persistence Units », Spécifié dans le fichier « persistence.xml » qui est
dans le jar contenant les EJBs. Exemple le plus simple :
Mais on peut ajouter de nombreux paramètres :<description>, <provider>, <transaction type>,
<mapping file> etc.
![Page 38: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/38.jpg)
Que faire avec un entity manager ?
![Page 39: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/39.jpg)
Etats d’un Entity Bean
Un EB peut avoir 4 états1. New: le bean existe en mémoire mais n’est pas encore
associé à une BD, il n’est pas encore associé à un contexte de persistence (via l’entity manager)
2. Managed : après le persist() par exemple. Le bean est associé avec les données dans la BD. Les changements seront répercutés (transaction terminées ou appel a flush())
3. Detached : le bean est n’est plus associé au contexte de persistenced
4. Removed : le bean est associé à la BD, au contexte, et est programmé pour être supprimé (les données seront supprimées aussi).
![Page 40: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/40.jpg)
Utilisation du persistent manager
Remove() pour supprimer des données,
Set(), Get(), appel de méthodes de l’entity bean pour modifier les données, mais le bean doit être dans un état « managed »,
Persist() pour créer des données, le bean devient managé,
Merge pour faire passer un bean « detached » dans l’état « managed ».
![Page 41: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/41.jpg)
Exemple de merge() avec le bean stateless
![Page 42: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/42.jpg)
Recherche d'entity beans
Les entity beans correspondant à des lignes dans une BD, on peut avoir besoin de faire des recherches.
Similaire à un SELECT
Plusieurs fonctions sont proposées par l’entity manager
![Page 43: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/43.jpg)
Recherche d’entity beans
Recherche par clé primaire :
Exécution de requêtes JPQL
![Page 44: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/44.jpg)
Recherche d’entity beans
Requêtes SQL:
Requêtes nommées:
![Page 45: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/45.jpg)
JPQL : Quelques exemples
Voir le fichier PDF fourni avec les TPs !
![Page 46: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/46.jpg)
JPQL : Quelques exemples (suite)
![Page 47: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/47.jpg)
JPQL : Quelques exemples (suite)
![Page 48: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/48.jpg)
JPQL : Quelques exemples (suite)
Liste toutes les commandes qui ne comprennent pas (LEFT) de produit dont le prix est supérieur à une certaine quantité (et celles qui ne comprennent pas de produits)
![Page 49: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/49.jpg)
JPQL : Quelques exemples (suite)
Requêter sur plusieurs attributs renvoie soit un tableau d’Object, soit une collection de tableaux d’Object
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]); }
![Page 50: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/50.jpg)
Table des compagnies
Table des employés
![Page 51: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/51.jpg)
JPQL : Quelques exemples (suite)
Cette requête récupère trois compagnies :
Mais celle-ci uniquement deux :
Celle-là : les trois (même si join condition absente)
![Page 52: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/52.jpg)
JPQL : Quelques exemples (suite)
Provoque le chargement des entities reliées
Prend le devant sur @FetchType.LAZY
Autre exemple :
![Page 53: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/53.jpg)
JPQL : Quelques exemples (suite)
WHERE et requêtes paramétrées
Autre exemple avec paramètres nommés
![Page 54: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/54.jpg)
JPQL : Quelques exemples (suite)
Expressions
Le % dans le LIKE = suite de caractères, le _ = un caractère
![Page 55: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/55.jpg)
JPQL : Quelques exemples (suite)
MEMBER OF
Sous-Requêtes
![Page 56: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/56.jpg)
Fonctions sur chaînes, arithmétique
![Page 57: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/57.jpg)
Fonctions sur chaînes, arithmétique (suite)
![Page 58: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/58.jpg)
JPQL : Quelques exemples (suite)
![Page 59: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/59.jpg)
JPQL : Quelques exemples (suite)
![Page 60: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/60.jpg)
Utiliser des colonnes composites
@Embeddable public class Address { protected String street; protected String city; protected String state; @Embedded Zipcode zipcode; }
@Embeddable public class Zipcode { String zip; protected String plusFour; }
![Page 61: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/61.jpg)
Utiliser une clé primaire composite
Similaire à l’exemple précédent sauf que au lieu d’utiliser @Embedded / @Embeddable on utilisera @EmbbededId / Embeddable
@Embeddable public class CompositeId { String name; String email}
@Entity public class Dependent { @EmbeddedId // indique que la clé primaire est dans une autre classe CompositeId id; @ManyToOne Employee emp; }
![Page 63: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/63.jpg)
On complique un peu l'étude des entity beans !
Les entity beans représentant des données dans une BD, il est logique d'avoir envie de s'occuper de gérer des relations
Exemples Une commande et des lignes de commande Une personne et une adresse Un cours et les élèves qui suivent ce cours Un livre et ses auteurs
Nous allons voir comment spécifier ces relations dans notre modèle EJB
![Page 64: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/64.jpg)
Concepts abordés
Cardinalité (1-1, 1-n, n-n…),
Direction des relations (bi-directionnelles, uni-directionnelles),
Agrégation vs composition et destructions en cascade,
Relations récursives, circulaires, agressive-load, lazy-load,
Intégrité référentielle,
Accéder aux relations depuis un code client, via des Collections,
Comment gérer tout ça !
![Page 65: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/65.jpg)
Direction des relations (directionality)
Unidirectionnelle On ne peut aller que du bean A vers le bean B
Bidirectionnelle On peut aller du bean A vers le bean B et
inversement
![Page 66: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/66.jpg)
Cardinalité
La cardinalité indique combien d'instances vont intervenir de chaque côté d'une relation
One-to-One (1:1) Un employé a une adresse…
One-to-Many (1:N) Un PDG et ses employés…
Many-to-Many (M:N) Des étudiants suivent des cours…
![Page 67: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/67.jpg)
Cardinalité
![Page 68: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/68.jpg)
Relations 1:1
Représentée typiquement par une clé étrangère dans une BD
Ex : une commande et un colis
![Page 69: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/69.jpg)
Relations 1:1, le bean Order
![Page 70: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/70.jpg)
Relations 1:1, le bean Order
![Page 71: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/71.jpg)
Relations 1:1, le bean Shipment
![Page 72: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/72.jpg)
Exemple de code pour insérer une commande avec une livraison reliée
![Page 73: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/73.jpg)
Relations 1:1, exemple de client (ici un main…)
![Page 74: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/74.jpg)
Version bidirectionnelle (on modifie Shipment)
![Page 75: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/75.jpg)
Version bidirectionnelle (suite)
![Page 76: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/76.jpg)
Version bi-directionnelle (suite, code qui fait le persist)
On peut maintenant ajouter au code de tout à l’heure (celui qui écrit une commande) :
![Page 77: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/77.jpg)
Version bi-directionnelle (suite, code du client)
![Page 78: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/78.jpg)
Relations 1:N
Exemple : une entreprise a plusieurs employés
![Page 79: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/79.jpg)
Relations 1:N
Exemple : une entreprise a plusieurs employés Solution plus propre (éviter les BLOBs!)
![Page 80: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/80.jpg)
Relations 1:N exemple
![Page 81: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/81.jpg)
Relations 1:N exemple
![Page 82: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/82.jpg)
Exemple de code qui insère des compagnies
![Page 83: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/83.jpg)
Exemple de code qui liste des compagnies
![Page 84: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/84.jpg)
Exemple de client
![Page 85: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/85.jpg)
Version bidirectionnelle
![Page 86: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/86.jpg)
Version bidirectionnelle
![Page 87: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/87.jpg)
Version bidirectionnelle
![Page 88: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/88.jpg)
Relations M:N
Un étudiant suit plusieurs cours, un cours a plusieurs étudiants inscrits Table de jointure nécessaire.
![Page 89: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/89.jpg)
Relations M:N, choix de conception
Deux possibilités lorsqu'on modélise cette relation avec des EJBs
1. Utiliser un troisième EJB pour modéliser la table de jointure. On veut peut-être mémoriser la date où un étudiant s'est inscrit, etc… Cet EJB possèdera deux relations 1:N vers le bean Student et le vers le bean Course
2. Si on n’a rien besoin de plus à part la relation, on peut utiliser simplement deux EJB, chacun ayant un attribut correspondant à une Collection de l'autre EJB…
![Page 90: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/90.jpg)
Relations M:N, exemple
![Page 91: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/91.jpg)
Relations M:N, exemple
![Page 92: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/92.jpg)
Relations M:N, exemple
![Page 93: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/93.jpg)
Relations M:N, exemple
![Page 94: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/94.jpg)
Relations M:N, exemple
![Page 95: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/95.jpg)
La directionalité et le modèle de données dans la DB
Qu’on soit en présence d’un modèle normalisé ou pas, les outils d’ORM s’adaptent.
Schéma normalisé
Schéma dénormalisé
![Page 96: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/96.jpg)
Choisir la directionalité ?
Premier critère : la logique de votre application,
Second critère : si le schéma relationnel existe, s'adapter au mieux pour éviter de mauvaises performances.
![Page 97: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/97.jpg)
Lazy-loading des relations
Agressive-loading Lorsqu'on charge un bean, on charge aussi tous les beans
avec lesquels il a une relation. Cas de la Commande et des Colis plus tôt dans ce chapitre. Peut provoquer un énorme processus de chargement si le
graphe de relations est grand.
Lazy-loading On ne charge les beans en relation que lorsqu'on essaie
d'accéder à l'attribut qui illustre la relation. Tant qu'on ne demande pas quels cours il suit, le bean
Etudiant n'appelle pas de méthode finder sur le bean Cours.
![Page 98: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/98.jpg)
Agrégation vs Composition et destructions en cascade
Relation par Agrégation Le bean utilise un autre bean Conséquence : si le bean A utilise le bean B, lorsqu'on détruit
A on ne détruit pas B. Par exemple, lorsqu'on supprime un étudiant on ne supprime
pas les cours qu'il suit. Et vice-versa.
Relation par Composition Le bean se compose d'un autre bean. Par exemple, une commande se compose de lignes de
commande… Si on détruit la commande on détruit aussi les lignes
correspondantes. Ce type de relation implique des destructions en cascade..
![Page 99: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/99.jpg)
Relations et JPQL
Lorsqu'on définit une relation en CMP, on peut aussi indiquer la requête qui permet de remplir le champs associé à la relation.
On fait ceci à l'aide de JPQL
SELECT o.customer
FROM Order o
Principale différence avec SQL, l'opérateur "." Pas besoin de connaître le nom des tables, ni le
nom des colonnes…
Renvoie tous les clients qui ont placé une commande
![Page 100: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/100.jpg)
Relations et EJB-QL
On peut aller plus loin…
SELECT o.customer.address.homePhoneNumber
FROM Order o
On se promène le long des relations…
![Page 101: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/101.jpg)
Relations récursives
Relation vers un bean de la même classe Exemple : Employé/Manager
Rien de particulier, ces relations sont implémentées exactement comme les relations non récursives…
![Page 102: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/102.jpg)
Relations circulaires
Similaire au relations récursives sauf qu'elles impliquent plusieurs types de beans Ex : un employé travaille dans une division, une division possède
plusieurs ordinateurs (workstation), une workstation est allouée à un employé…
Ce type de relation, en cas de agressive-loading peut mener à une boucle sans fin… Même problème avec les destructions en cascade…
![Page 103: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/103.jpg)
Relations circulaires
Plusieurs stratégies sont possibles1. Certains containers proposent d'optimiser le chargement
d'un bean en chargeant toutes ses relations en cascade. Attention si relations circulaires !
2. Supprimer une des relations (!!!) si le modèle de conception le permet.
3. Supprimer la bidirectionnalité d'une des relations pour briser le cercle, si le modèle de conception le permet.
4. Utiliser le lazy-loading et ne pas faire de destruction en cascade.
5. Les meilleurs moteurs CMP détectent les relations circulaires et vous permettent de traiter le problème avant le runtime.
![Page 104: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/104.jpg)
Intégrité référentielle
Un bean Compagnie, Division, etc… a des relations avec un bean Employé Si on supprime un employé, il faut vérifier qu'il est
bien supprimé partout où on a une relation avec lui.
Problème classique dans les SGBDs Résolus à l'aide de triggers. Ils se déclenchent sitôt
qu'une perte d'intégrité risque d'arriver et effectuent les opérations nécessaires.
On peut aussi utiliser des procédures stockées via JDBC. Ces procédures effectuent la vérification d'intégrité.
![Page 105: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/105.jpg)
Intégrité référentielle
Gérer l'intégrité dans le SGBD est intéressant si la BD est attaquée par d'autres applications que les EJBs…
Autre approche : gérer l'intégrité dans les EJBs Solution plus propre, Le SGBD n'est plus aussi sollicité, Avec les EJB: le travail est fait tout seul !
![Page 106: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/106.jpg)
Intégrité référentielle
Et dans un contexte distribué ?
Plusieurs serveurs d'application avec le même composant peuvent accèder à des données sur le même SGBD,
Comment mettre à jour les relations ?
Problème résolu par les transactions !!!
![Page 107: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/107.jpg)
Trier les relations
Lorsqu’on accède aux relations par un getter, on ne contrôle pas par défaut l’ordre des éléments.
Plusieurs solutions sont possibles pour récupérer des relations sous forme de collections triées Utiliser l’annotation @OrderBy juste avant la
déclaration de la relation ou juste avant le getter Utiliser une requête avec un Order By Annoter l’attribut correspondant à la colonne qui sera
ordonnée, dans l’entity de la relation
![Page 108: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/108.jpg)
Trier des relations : annotation @OrderBy
@Entity public class Course { ... @ManyToMany @OrderBy("lastname ASC") List<Student> students; ... }
Remarques ASC ou DESC pour l’ordre de tri, ASC par défaut, lastname est une propriété de l’entité Student.java, Si la propriété n’est pas spécifiée -> tri par l’id
![Page 109: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/109.jpg)
Trier des relations : annotation @OrderBy
@Entity public class Student { ... @ManyToMany(mappedBy="students") @OrderBy // tri par clé primaire (défaut) List<Course> courses; ... }
Remarques ASC ou DESC pour l’ordre de tri, ASC par défaut, lastname est une propriété de l’entité Student.java, Si la propriété n’est pas spécifiée -> tri par l’id
![Page 110: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/110.jpg)
Trier des relations : annotation @OrderBy
On peut utiliser l’opérateur « . » si on trie sur une colonne qui est définie dans une autre classe par @Embedded
@Entity public class Person { ... @ElementCollection @OrderBy("zipcode.zip, zipcode.plusFour") Set<Address> residences; ... }
![Page 111: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/111.jpg)
Trier des relations : annotation @OrderBy
@Embeddable public class Address { protected String street; protected String city; protected String state; @Embedded Zipcode zipcode; }
@Embeddable public class Zipcode { String zip; protected String plusFour; }
![Page 112: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/112.jpg)
Supprimer des relations
Piège classique !
On ne peut pas supprimer une relation si elle est partagée par un autre objet. Ex: une classe Personne a une collection
d’Adresses (Adresse.java est une classe entité), on a une relation 1-N.
Si une de ces adresses est aussi en relation avec une autre Personne, il y a aura une erreur.
Voyons quelques exemples…
![Page 113: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/113.jpg)
Supprimer des relations
Supposons que nous ne sommes pas dans le cas précédent. Les relations ne sont pas partagées…
Premier cas: on a une relation 1-N entre Personne et Adresse Normalement si on génère des tables à partir de
ces classes on a une table de jointure générée
![Page 114: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/114.jpg)
Relation 1-N unidirectionnelle non partagée
Si on supprime un élément de la collection, une adresse, et que l’objet personne est « managé » donc synchronisé avec la BD Une ligne dans la table de jointure est supprimée, L’adresse n’est pas supprimée
Si on est en CascadeType.REMOVE ou CascadeType.ALL alors : L’adresse est supprimée également Attention, que si elle n’est pas partagée !!!
![Page 115: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/115.jpg)
Relation 1-N bi-directionnelle non partagée
![Page 116: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/116.jpg)
Relation 1-N bi-directionnelle non partagée
A part qu’on a pas de table de jointure, le principe est le même que pour les exemples uni-directionnels. Si on supprime une adresse de la collection, alors
on va mettre à null la clé étrangère dans la table des ADRESSE, mais l’adresse n’est pas supprimée,
Si on est en CascadeType.REMOVE ou CascadeType.ALL alors la ligne de l’adresse est supprimée dans la table des adresses.
![Page 117: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/117.jpg)
Cas des relations partagées
On ne peut pas supprimer une relation partagée, donc comment faire ? Avant de la supprimer de la collection, s’assure
qu’elle n’est pas partagée, Si elle l’est, voir si il ne faut pas d’abord supprimer
l’entité qui la partage…
Attention aux destructions en cascade !!!!
![Page 118: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/118.jpg)
Cas des relations partagées
Si on est en CascadeType.REMOVE ou CascadeType.ALL la suppression d’une personne implique la suppression d’une adresse, ce qui peut aussi donner des erreurs.
Solution: utiliser l’attribut orphanRemoval=true
Cela ne va supprimer les adresses que si elles sont orphelines.
Sinon : ne pas faire de delete en cascade et gérer à la main.
![Page 119: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/119.jpg)
Relations N-N
Cas similaires mais un peu plus compliqué
Ex: des cours et des élèves, comment supprimer un cours ou un élève
Solution recommandée : ne pas faire de delete en cascade utiliser l’attribut orphanRemoval=true si on ne veut
pas de données orphelines.
![Page 120: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/120.jpg)
Concepts avancés sur la persistence
![Page 121: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/121.jpg)
Introduction
Et le polymorphisme ?
Et l’héritage ?
Et EJB-QL ?
![Page 122: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/122.jpg)
Héritage
Stratégies de mapping entre classes et tables quand on a de l’héritage ? Une table pour toute la hiérarchie de classes ? Une table par classe/sous-classe ? Autres solutions ?
![Page 123: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/123.jpg)
Un exemple !
![Page 124: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/124.jpg)
Code de RoadVehicle.java (classe racine)
![Page 125: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/125.jpg)
Code de Motorcycle.java
![Page 126: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/126.jpg)
Code de Car.java
![Page 127: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/127.jpg)
Code de Roadster.java
![Page 128: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/128.jpg)
Code de Coupe.java
![Page 129: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/129.jpg)
Premier cas : une seule table !
Une seule table représente toute la hiérarchie.
Une colonne de « discrimination » est utilisée pour distinguer les sous-classes.
Cette solution supporte le polymorphisme.
Désavantages : Une colonne pour chaque champ de chaque classe, Comme une ligne peut être une instance de chaque
classe, des champs risquent de ne servir à rien (nullable)
![Page 130: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/130.jpg)
Regardons le code avec les annotations !
![Page 131: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/131.jpg)
(suite)
![Page 132: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/132.jpg)
Motorcycle.java annoté !
![Page 133: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/133.jpg)
Car.java annoté
![Page 134: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/134.jpg)
Roadster.java annoté
![Page 135: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/135.jpg)
Coupe.java annoté
![Page 136: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/136.jpg)
Table correspondante
![Page 137: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/137.jpg)
Quelques objets persistants !
![Page 138: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/138.jpg)
Et les données correspondantes
![Page 139: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/139.jpg)
Deuxième stratégie : une table par classe
Il suffit de modifier quelques annotations ! Dans RoadVehicle.java
On peut retirer les @Discriminator des sous-classes (on aura des valeurs par défaut)
Le champ Id de la classe RoadVehicle sera une clé étrangère dans les tables des sous-classes,
Remarque : on utilise ici @TABLE pour ne pas que la table porte le même nom que dans l’exemple précédent (facultatif)
![Page 140: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/140.jpg)
Les tables !
![Page 141: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/141.jpg)
Les tables (suite)
![Page 142: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/142.jpg)
Requête SQL pour avoir tous les Roadsters
Il faut faire des joins !
Plus la hierarchie est profonde, plus il y aura de jointures : problèmes de performance !
![Page 143: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/143.jpg)
Conclusion sur cette approche
Supporte le polymorphisme,
On alloue juste ce qu’il faut sur disque,
Excellente approche si on a pas une hiérarchie trop profonde,
A éviter sinon…
![Page 144: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/144.jpg)
Autres approches
Des classes qui sont des entity bean peuvent hériter de classes qui n’en sont pas,
Des classes qui ne sont pas des entity beans peuvent hériter de classes qui en sont,
Des classes abstraites peuvent être des entity beans,
(déjà vu : une classe qui est un entity bean hérite d’une autre classe qui est un entity bean)
![Page 145: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/145.jpg)
Cas 1 : Entity Bean étends classe java
On utilise l’attribut @mappedsuperclass dans la classe mère Indique qu’aucune table ne lui sera associée
![Page 146: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/146.jpg)
Cas 1 (les sous-classes entities)
![Page 147: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/147.jpg)
Cas 1 : les tables
![Page 148: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/148.jpg)
Remarques sur le cas 1
RoadVehicle n’aura jamais sa propre table,
Les sous-classes auront leur propre table, avec comme colonnes les attributs de RoadVehicle en plus des leurs,
Si on n’avait pas mis @MappedSuperclass dans RoadVehicle.java, les attributs hérités n’auraient pas été des colonnes dans les tables des sous-classes.
![Page 149: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/149.jpg)
Classe abstraite et entity bean
Une classe abstraite peut être un entity bean (avec @entity)
Elle ne peut pas être instanciée, ses sous-classes concrètes oui,
Elle aura une table dédiée,
Elle pourra faire l’objet de requêtes (polymorphisme) : très intéressant !
![Page 150: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/150.jpg)
Polymorphisme ! Exemple avec un SessionBean
![Page 151: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/151.jpg)
Polymorphisme (suite)
Des requêtes polymorphes ! Si ! Si !
![Page 152: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/152.jpg)
Polymorphisme : code client
![Page 153: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/153.jpg)
Polymorphisme : oui, ça marche !
C’est bien la méthode toString() de chaque sous-classe qui est appelée !
La requête à récupéré tous les RoadVehicle (s)
![Page 154: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/154.jpg)
JPQL : Quelques exemples
Voir le fichier PDF fourni avec les TPs !
![Page 155: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/155.jpg)
JPQL : Quelques exemples (suite)
![Page 156: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/156.jpg)
JPQL : Quelques exemples (suite)
![Page 157: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/157.jpg)
JPQL : Quelques exemples (suite)
Liste toutes les commandes qui ne comprennent pas (LEFT) de produit dont le prix est supérieur à une certaine quantité (et toutes celles qui n’ont pas de produits)
![Page 158: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/158.jpg)
Table des compagnies
Table des employés
![Page 159: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/159.jpg)
JPQL : Quelques exemples (suite)
Cette requête récupère trois compagnies :
Mais celle-ci uniquement deux :
Celle-là en ramène trois aussi (le left matche celles qui n’ont pas de jointure)
![Page 160: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/160.jpg)
JPQL : Quelques exemples (suite)
Provoque le chargement des entities reliées
Prend le devant sur @FetchType.LAZY
Autre exemple :
![Page 161: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/161.jpg)
JPQL : Quelques exemples (suite)
WHERE et requêtes paramétrées
Autre exemple avec paramètres nommés
![Page 162: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/162.jpg)
JPQL : Quelques exemples (suite)
Expressions
Le % dans le LIKE = suite de caractères, le _ = un caractère
![Page 163: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/163.jpg)
JPQL : Quelques exemples (suite)
MEMBER OF
Sous-Requêtes
![Page 164: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/164.jpg)
Fonctions sur chaînes, arithmétique
![Page 165: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/165.jpg)
Fonctions sur chaînes, arithmétique (suite)
![Page 166: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/166.jpg)
JPQL : Quelques exemples (suite)
![Page 167: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/167.jpg)
JPQL : Quelques exemples (suite)
![Page 169: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/169.jpg)
Message-Driven Beans
Nouveauté apparue avec EJB 2.0,
Messaging = moyen de communication léger, comparé à RMI-IIOP,
Pratique dans de nombreux cas,
Message-Driven beans = beans accessibles par messaging asynchrone.
![Page 170: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/170.jpg)
Message-Driven Beans : motivation
Performance Un client RMI-IIOP attend pendant que le serveur
effectue le traitement d'une requête,
Fiabilité Lorsqu'un client RMI-IIOP parle avec un serveur, ce
dernier doit être en train de fonctionner. S'il crashe, ou si le réseau crashe, le client est coincé.
Pas de broadcasting ! RMI-IIOP limite les liaisons 1 client vers 1 serveur
![Page 171: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/171.jpg)
Messaging
C'est comme le mail ! Ou comme si on avait une troisième personne entre le client et le serveur !
![Page 172: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/172.jpg)
Messaging
A cause de ce "troisième homme" les performances ne sont pas toujours au rendez-vous !
Message Oriented Middleware (MOM) est le nom donné aux middlewares qui supportent le messaging. Tibco Rendezvous, IBM MQSeries, BEA Tuxedo/Q, Microsoft
MSMQ, Talarian SmartSockets, Progress SonicMQ, Fiorano FioranoMQ, …
Ces produits fournissent : messages avec garantie de livraison, tolérance aux fautes, load-balancing des destinations, etc…
![Page 173: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/173.jpg)
The Java Message Service (JMS)
Les serveurs MOM sont pour la plupart propriétaires : pas de portabilité des applications !
JMS = un standard pour normaliser les échanges entre composant et serveur MOM, Une API pour le développeur, Un Service Provider Interface (SPI), pour rendre
connecter l'API et les serveurs MOM, via les drivers JMS
![Page 174: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/174.jpg)
JMS : Messaging Domains
Avant de faire du mesaging, il faut choisir un domaine Domaine = type de messaging
Domaines possibles Publish/Subscribe (pub/sub) : n
producteurs, n consommateurs (tv)
Point To Point (PTP) : n producteurs, 1 consommateur
![Page 175: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/175.jpg)
JMS : les étapes
1. Localiser le driver JMS lookup JNDI. Le driver est une connection factory
2. Créer une connection JMS obtenir une connection à partir de la connection factory
3. Créer une session JMS Il s'agit d'un objet qui va servir à recevoir et envoyer des messages.
On l'obtient à partir de la connection.
4. Localiser la destination JMS Il s'agit du canal, de la chaîne télé ! Normalement, c'est réglé par le
déployeur. On obtient la destination via JNDI.
5. Créer un producteur ou un consommateur JMS Utilisés pour écrire ou lire un message. On les obtient à partir de la
destination ou de la session.
6. Envoyer ou recevoir un message
![Page 176: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/176.jpg)
JMS : les étapes
![Page 177: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/177.jpg)
JMS : les interfaces
![Page 178: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/178.jpg)
JMS : exemple de code (1)
![Page 179: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/179.jpg)
JMS : exemple de code (2)
Note : Dans 3) false = pas de transactions, AUTO_AKNOWLEDGE = inutile ici puisqu’on envoie des messages.
![Page 180: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/180.jpg)
Intégrer JMS et les EJB
Pourquoi créer un nouveau type d'EJB ?
Pourquoi ne pas avoir délégué le travail à un objet spécialisé ?
Pourquoi ne pas avoir augmenté les caractéristiques des session beans ?
Parce que ainsi on peut bénéficier de tous les avantages déjà rencontrés : cycle de vie, pooling, descripteurs spécialisés, code simple…
![Page 181: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/181.jpg)
Qu'est-ce qu'un Message-Driven Bean ?
Un EJB qui peut recevoir des messages Il consomme des messages depuis les queues ou
topics, envoyés par les clients JMS
![Page 182: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/182.jpg)
Qu'est-ce qu'un Message-Driven Bean ?
Un client n'accède pas à un MDB via une interface, il utilise l'API JMS,
Un MDB n'a pas d'interface Home, Local Home, Remote ou Local,
Les MDB possèdent une seule méthode, faiblement typée : onMessage() Elle accepte un message JMS (BytesMessage, ObjectMessage,
TextMessage, StreamMessage ou MapMessage) Pas de vérification de types à la compilation. Utiliser instanceof au run-time pour connaître le type du
message.
Les MDB n'ont pas de valeur de retour Ils sont découplés des producteurs de messages.
![Page 183: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/183.jpg)
Qu'est-ce qu'un Message-Driven Bean ?
Pour envoyer une réponse à l'expéditeur : plusieurs design patterns…
Les MDB ne renvoient pas d'exceptions au client (mais au container),
Les MDB sont stateless…
Les MDB peuvent être des abonnés durables ou non-durables (durable or nondurable subscribers) à un topic Durable = reçoit tous les messages, même si l'abonné est
inactif, Dans ce cas, le message est rendu persistant et sera délivré
lorsque l'abonné sera de nouveau actif. Nondurable = messages perdus lorsque abonné inactif.
![Page 184: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/184.jpg)
Qu'est-ce qu'un Message-Driven Bean ?
Le consommateur (celui qui peut les détruire) des messages est en général le Container C'est lui qui choisit d'être durable ou non-durable, S'il est durable, les messages résistent au crash du
serveur d'application.
![Page 185: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/185.jpg)
Développer un Message-Driven Bean
Les MDBs doivent implémenter public interface javax.jms.MessageListener {
public void onMessage(Message message);
}
public interface javax.ejb.MessageDrivenBean
extends EnterpriseBean {
public void ejbRemove()
throws EJBException;
public void setMessageDrivenContext(MessageDrivenContext ctx)
throws EJBException;
}
La classe d'implémentation doit fournir une méthode ejbCreate() qui renvoit void et qui n'a pas d'arguments.
![Page 186: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/186.jpg)
Développer un Message-Driven Bean
Méthodes qui doivent être implémentées onMessage(Message)
Invoquée à chaque consommation de messageUn message par instance de MBD, pooling
assuré par le container setMessageDrivenContext(MessageDrivenContext)Appelée avant ejbCreate, sert à récupèrer le
contexte.Ne contient que des méthodes liées aux
transactions…
![Page 187: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/187.jpg)
Développer un Message-Driven Bean
![Page 188: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/188.jpg)
Un exemple simple
Un MDB qui fait du logging, c'est à dire affiche des messages de textes à l'écran chaque fois qu'il consomme un message. Utile pour débugger….
Rappel : pas d'interfaces !
![Page 189: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/189.jpg)
La classe du bean
![Page 190: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/190.jpg)
La classe du bean (suite)
![Page 191: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/191.jpg)
Question ?
Comment sait-on quelle queue ou quel topic de messages le bean consomme ? Cela n'apparaît pas dans le descripteur !
C'est fait exprès pour rendre les MDB portables et réutilisables.
L'information se trouve dans l’@ActivationConfigProperty au début du code
![Page 192: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/192.jpg)
Exemple de descripteur spécifique, tiré d'un autre exemple (Borland)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Borland Software Corporation//DTD Enterprise JavaBeans 2.0//EN" "http://www.borland.com/devsupport/appserver/dtds/ejb-jar_2_0-borland.dtd">
<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>HelloEJBQueue</ejb-name>
<message-driven-destination-name>serial://jms/q</message-driven-destination-name>
<connection-factory-name>serial://jms/xaqcf</connection-factory-name>
<pool>
<max-size>20</max-size>
<init-size>2</init-size>
</pool>
</message-driven>
<message-driven>
<ejb-name>HelloEJBTopic</ejb-name>
<message-driven-destination-name>serial://jms/t</message-driven-destination-name>
<connection-factory-name>serial://jms/tcf</connection-factory-name>
<pool>
<max-size>20</max-size>
<init-size>2</init-size>
</pool>
</message-driven>
</enterprise-beans>
</ejb-jar>
![Page 193: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/193.jpg)
Le client (1)
import javax.naming.*;
import javax.jms.*;
import java.util.*;
public class Client {
public static void main (String[] args) throws Exception {
// Initialize JNDI
Context ctx = new InitialContext(System.getProperties());
// 1: Lookup ConnectionFactory via JNDI
TopicConnectionFactory factory =
(TopicConnectionFactory)
ctx.lookup("javax.jms.TopicConnectionFactory");
// 2: Use ConnectionFactory to create JMS connection
TopicConnection connection =
factory.createTopicConnection();
![Page 194: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/194.jpg)
Le client (2)
// 3: Use Connection to create session
TopicSession session = connection.createTopicSession(
false, Session.AUTO_ACKNOWLEDGE);
// 4: Lookup Destination (topic) via JNDI
Topic topic = (Topic) ctx.lookup("testtopic");
// 5: Create a Message Producer
TopicPublisher publisher = session.createPublisher(topic);
// 6: Create a text message, and publish it
TextMessage msg = session.createTextMessage();
msg.setText("This is a test message.");
publisher.publish(msg);
}
}
![Page 195: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/195.jpg)
Concepts avancés
Transactions et MBD, La production et la consommation du message sont dans
deux transactions séparées…
Sécurité, Les MDB ne reçoivent pas les informations de sécurité du
producteur avec le message. On ne peut pas effectuer les opérations classiques de sécurité sur les EJB.
Load-Balancing, Modèle idéal : les messages sont dans une queue et ce sont
les MDB qui consomment, d'où qu'ils proviennent. Comparer avec les appels RMI-IIOP pour les session et entity
beans, ou on ne peut que faire des statistiques…
![Page 196: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/196.jpg)
Concepts avancés
Consommation dupliquée dans les architectures en clusters : utiliser une queue au lieu d'un topic si on veut que le message ne soit consommé qu'une fois !
Chaque container est un consommateur !
![Page 197: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/197.jpg)
Concepts avancés
![Page 198: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/198.jpg)
Pièges !
Ordre des messages Le serveur JMS ne garantit pas l'ordre de livraison
des messages.
L'appel à ejbRemove() n'est pas garanti, comme pour les session beans stateless… A cause du pooling, En cas de crash.
Messages empoisonnés (poison messages) A cause des transactions un message peut ne
jamais être consommé
![Page 199: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/199.jpg)
Pièges !
Messages empoisonnés (poison messages) A cause des transactions un message peut ne
jamais être consommé
![Page 200: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/200.jpg)
MDB empoisonné !
package examples;
import javax.ejb.*;
import javax.jms.*;
public class PoisonBean
implements MessageDrivenBean, MessageListener {
private MessageDrivenContext ctx;
public void setMessageDrivenContext(MessageDrivenContext ctx) {
this.ctx = ctx;
}
public void ejbCreate() {}
public void ejbRemove() {}
...
![Page 201: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/201.jpg)
MDB empoisonné !
...
public void onMessage(Message msg) {
try {
System.out.println("Received msg " + msg.getJMSMessageID());
// Let's sleep a little bit so that we don't see rapid fire re-sends of the message.
Thread.sleep(3000);
// We could either throw a system exception here or
// manually force a rollback of the transaction.
ctx.setRollbackOnly();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
![Page 202: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/202.jpg)
MDB empoisonné !
Solutions Ne pas lever d'exception, Utiliser des transactions gérées par le bean, non par
le container, Certains serveurs peuvent configurer une "poison
message queue" ou posséder un paramètre "nb max retries"
…
![Page 203: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/203.jpg)
Comment renvoyer des résultats à l'expéditeur du message ?
A faire à la main ! Rien n'est prévu !
![Page 204: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/204.jpg)
Comment renvoyer des résultats à l'expéditeur du message ?
Néanmoins, des problèmes se posent si le client est lui-même un EJB de type stateful session bean Que se passe-t-il en cas de passivation ? Perte de la connexion à la destination temporaire!
Solution : ne pas utiliser d'EJB SSB comme client! Utiliser une Servlet ou un JSP
Autre solution : configurer un topic permanent pour les réponses, au niveau du serveur JMS.
![Page 205: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/205.jpg)
Comment renvoyer des résultats à l'expéditeur du message ?
![Page 206: Persistance dans Java EE 6 : JPA2 et EJB 3.1](https://reader035.vdocuments.mx/reader035/viewer/2022062723/56813e59550346895da85102/html5/thumbnails/206.jpg)
Comment renvoyer des résultats à l'expéditeur du message ?
D'autres solutions existent…
JMS propose deux classes javax.jms.QueueRequestor et javax.jms.TopicRequestor qui implémentent une pattern simple question/réponse
Solution bloquante, pas de gestion de transactions…
JAVA EE 6: invocation de méthode asynchrone !