Les Entity Beans
Transcription
Les Entity Beans
Les Entity Beans • Un entity bean est un objet métier persistant ; • un entity bean peut être partagé par plusieurs clients. • Exemples de la gestion d’une médiatèque : Adhérent, Œuvre, Exemplaire Les Entity Beans 1RP 3UpQRP $GUHVVH Durand Paul 15 impasse nul part Dupond Albert 2 allée Tataouine Persistance Base de données Benoît Charroux - Entity Beans - Mars 00 - 2 1 Les propriétés des entity beans (1/2) • Les entity beans peuvent être SHUVLVWDQWV, SDUWDJpV par plusieurs clients : Les propriétés des entity beans (2/2) • chaque entity bean a une clef (primary key) permettant de l’identifier ; • les associations (leurs navigabilités et leurs multiplicités) entre composants sont gérées : • persistance : • automatiquement pour les container-managed-persistent beans ; • c’est au déploiement qu’on précise si un bean doit être persistant ; • par le développeur pour les bean-managed-persistent beans. • bean managed : il faut écrire le code pour la persistance ; • container managed : c’est le conteneur qui se charge de la persistance ; • le partage d’un entity bean : • si un bean est partagé ⇒ l’encapsuler dans une transaction pour maintenir un état consistant pendant qu’un client l’utilise ; • les transactions sont spécifiées au moment du déploiement ; Benoît Charroux - Entity Beans - Mars 00 - 3 Benoît Charroux - Entity Beans - Mars 00 - 4 2 Container-managed versus Bean-managed persistence Container-managed Les restrictions des Container-managed persistence beans Bean-managed • Les principales restrictions de la version 1.2.1 du Java 2 sdk Enterprise Edition sont : • Les beans sont simples ; • Les beans sont plus complexes ; • quand un champs d’un objet est chargé, tous les autres champs le sont aussi ; • les champs persistants et les requêtes sont précisées lors du déploiement ; • si des champs dans plusieurs entity beans font références au même champs d’une base de données dans une transaction, il peut y avoir inconsistance des données ; • indépendant du support (base de données relationnelle ou objet) ; • on ne peut pas utiliser de procédures dans les requêtes SQL générées ; • Consommateur de ressources. • ... • utile pour éviter certaines restrictions des Container Managed Persistence Beans. Benoît Charroux - Entity Beans - Mars 00 - 5 Benoît Charroux - Entity Beans - Mars 00 - 6 3 Développer un entity bean container managed-persistent -DYDLR6HULDOL]DEOH -DYD[HME(QWHUSULVH%HDQ • La classe qui définit un entity bean doit : • implémenter l’interface EntityBean ; • être déclarée public ; Développer un entity bean container managed-persistence -DYD[HME(QWLW\%HDQ HME$FWLYDWH HME3DVVLYDWH HME/RDG • doit être abstraite ; HME5HPRYH • implémente une ou plusieurs méthodes ejbCreate et ejbPostCreate ; • a un constructeur vide ; • ne doit pas définir une méthode finalize ; • son état est représenté par des champs virtuelles et des méthodes d’accès. HME6WRUH VHW(QWLW\&RQWH[W XQVHW(QWLW\&RQWH[W MonEntityBean methodes ejbCreate( Arg arg ) ejbPostCreate Benoît Charroux - Entity Beans - Mars 00 - 8 4 L’état d’un container managed persistance bean Les méthodes métiers • Les champs persistants sont déduits automatiquement => il faut se conformer aux règles des Java Beans : • Les méthodes métiers n’accèdent pas généralement à une base de données afin de les public abstract class MonEJB implements EntityBean{ public String ejbCreate( String nom ) throws CreateException{ if( nom==null ){ throw new CreateException("..."); } • 2 champs persistants seront déduits : setClefPrimaire( … ); • String nom ; setNom( nom ); return null ; • String clefPrimaire ; } public abstract String getClefPrimaire(); public abstract void setClefPrimaire( String clefPrimaire ); public abstract String getNom(); public abstract void setNom( String nom ); // … } Benoît Charroux - Entity Beans - Mars 00 - 9 rendre indépendantes du système de stockage ; • elles doivent être public, mais ni static, ni final ; • leurs arguments doivent être compatibles avec RMI dans le cas des beans accessibles à distances. Benoît Charroux - Entity Beans - Mars 00 - 10 5 Exemple d’un entity bean 1/2 Exemple d’un container-managed persistance bean public abstract class MonEJB implements EntityBean{ public String ejbCreate( String nom ) throws CreateException{ if( nom==null ){ -DYDLR6HULDOL]DEOH throw new CreateException("..."); } String id = nom + "-" + 1; -DYD[HME(QWHUSULVH%HDQ setClefPrimaire( id ); setNom( nom ); return id ; -DYD[HME(QWLW\%HDQ } HME$FWLYDWH public abstract String getClefPrimaire(); HME3DVVLYDWH public abstract void setClefPrimaire( String clefPrimaire ); HME/RDG public abstract String getNom(); HME5HPRYH public abstract void setNom( String nom ); HME6WRUH public void ejbPostCreate( String nom ) throws CreateException{} VHW(QWLW\&RQWH[W // … XQVHW(QWLW\&RQWH[W } Benoît Charroux - Entity Beans - Mars 00 - 12 6 Exemple d’un entity bean 2/2 public abstract class MonEJB implements EntityBean{ // … private EntityContext context; public void ejbActivate(){} public void ejbLoad(){} public void ejbPassivate(){} public void ejbRemove(){} public void ejbStore(){} public void setEntityContext( EntityContext ctx ){ context = ctx; } public void unsetEntityContext(){ context = null; } } -DYDLR6HULDOL]DEOH -DYD[HME(QWHUSULVH%HDQ -DYD[HME(QWLW\%HDQ HME$FWLYDWH HME3DVVLYDWH HME/RDG HME5HPRYH Les interfaces pour un client distant HME6WRUH VHW(QWLW\&RQWH[W XQVHW(QWLW\&RQWH[W Benoît Charroux - Entity Beans - Mars 00 - 13 7 Les interfaces distantes EJBHome stub (-%+RPH LQWHUIDFH Les interfaces homes et distantes • L’interface home est utilisée par le client pour créer et trouver un entity bean : KRPH LQWHUIDFH create() EJBHome • la méthode create() retourne au client une référence distance et un stub. • Le conteneur créé un objet EJB, un bean et appel de ejbCreate() : bean &OLHQWGLVWDQW ejbCreate() EJBObject • Dans le cas d’un entityBean, insertion d’un enregistrement dans la base : 6HUYHXUHWFRQWHQHXU EJBObject stub (-%2EMHFW UHPRWH LQWHUIDFH -DYDUPL5HPRWH -DYD[HME(-%2EMHFW -DYD[HME(-%+RPH 0RQ,QWHUIDFH'LVWDQWH 0RQ,QWHUIDFH+RPH PHWKRGHV • La méthode create() retourne au client une référence distance et un stub : Benoît Charroux - Introduction - Mars 00 - 15 Fonctionnalités du composant 0RQ,QWHUIDFH'LVWDQWHFUHDWH$UJDUJ 0RQ,QWHUIDFH'LVWDQWHILQG%\3ULPDU\.H\« Cycle de vie du composant : création, recherche, suppression. Benoît Charroux - Entity Beans - Mars 00 - 16 8 Exemple d’une interface home Exemple d’une interface distante 0RQ,QWHUIDFH+RPH 0RQ,QWHUIDFH'LVWDQWH 0RQ,QWHUIDFH'LVWDQWHFUHDWH$UJDUJ PHWKRGHV 0RQ,QWHUIDFH'LVWDQWHILQG%\3ULPDU\.H\« public interface AdherentHome extends EJBHome{ public Adherent create( String nom ) throws … ; public Adherent findByPrimaryKey( String clefPrimaire ) throws … ; public Collection findByNom( String nom ) throws … ; } • Utilisation par un client : public interface Adherent extends EJBObject{ public String getNom() throws RemoteException ; } • Utilisation par un client : Context initial = new InitialContext(); Object objref = initial.lookup( "MonAdherent" ); AdherentHome home = (AdherentHome)PortableRemoteObject.narrow( objref, AdherentHome.class ) ; Adherent durand = home.create( "Durand" ) ; Benoît Charroux - Entity Beans - Mars 00 - 17 ... Adherent durand = home.create( "Durand", "Albert" ) ; System.out.println( durand.getNom() ) ; Benoît Charroux - Entity Beans - Mars 00 - 18 9 Les interfaces locales Les interfaces pour un client situé dans le même conteneur Client local Home interface EJBHome Remote interface EJBObject Bean /RFDOLQWHUIDFH /RFDOKRPH LQWHUIDFH EJBLocalObject Bean EJBLocalHome Conteneur EJB Serveur EJB Benoît Charroux - Introduction - Mars 00 - 20 10 Les interfaces homes et locales Exemple d’une interface home 0RQ,QWHUIDFH+RPH • L’interface home est utilisée par le client pour créer et trouver un entity bean : • la méthode create() retourne au client une référence locale. 0RQ,QWHUIDFH/RFDOHFUHDWH$UJDUJ 0RQ,QWHUIDFH/RFDOHILQG%\3ULPDU\.H\« -DYD[HME(-%/RFDO2EMHFW -DYD[HME(-%/RFDO+RPH 0RQ,QWHUIDFH/RFDOH 0RQ,QWHUIDFH/RFDOH PHWKRGHV 0RQ,QWHUIDFH/RFDOHFUHDWH$UJDUJ 0RQ,QWHUIDFH/RFDOHILQG%\3ULPDU\.H\« Fonctionnalités du composant Cycle de vie du composant : création, recherche, suppression. Benoît Charroux - Entity Beans - Mars 00 - 21 public interface LocalAdherentHome extends EJBLocalHome{ public LocalAdherent create( String nom ) throws … ; public LocalAdherent findByPrimaryKey( String clefPrimaire ) throws … ; public Collection findByNom( String nom ) throws … ; } • Utilisation par un client : Context initial = new InitialContext(); Object objref = initial.lookup( "MonAdherent" ); LocalAdherentHome home = (LocalAdherentHome)PortableRemoteObject.narrow( objref, LocalAdherentHome.class ) ; LocalAdherent durand = home.create( "Durand" ) ; Benoît Charroux - Entity Beans - Mars 00 - 22 11 Exemple d’une interface distante 0RQ,QWHUIDFH/RFDOH PHWKRGHV public interface LocalAdherent extends EJBLocalObject{ public String getNom(); } Déployer un container-managed persistence bean avec le deploytool • Utilisation par un client : ... LocalAdherent durand = home.create( "Durand" ) ; System.out.println( durand.getNom() ) ; Benoît Charroux - Entity Beans - Mars 00 - 23 12 Champs persistants découverts par introspection Saisie des requêtes pour les méthodes de recherche public interface LocalAdherentHome extends EJBLocalHome{ public LocalAdherent create( String nom ) throws … ; public LocalAdherent findByPrimaryKey( String clefPrimaire ) throws … ; SXEOLF&ROOHFWLRQ ILQG%\1RP6WULQJQRP WKURZV« } Benoît Charroux - Entity Beans - Mars 00 - 25 Benoît Charroux - Entity Beans - Mars 00 - 26 13 Le choix des attributs de transaction Le choix des attributs de sécurité Benoît Charroux - Entity Beans - Mars 00 - 27 Benoît Charroux - Entity Beans - Mars 00 - 28 14 La génération automatique de requêtes SQL pour les champs persistants 1RP 3UpQRP $GUHVVH Durand Paul 15 impasse nul part Dupond Albert 2 allée Tataouine Choix d’un nom pour le service de nommage • Utilisation par un client : Persistance Context initial = new InitialContext(); 2EMHFWREMUHI LQLWLDOORRNXS$GKHUHQW LocalAdherentHome home = (LocalAdherentHome)PortableRemoteObject.narrow( objref, LocalAdherentHome.class ) ; LocalAdherent durand = home.create( "Durand" ) ; Benoît Charroux - Entity Beans - Mars 00 - 29 Benoît Charroux - Entity Beans - Mars 00 - 30 15 Extrait du descripteur de déploiement généré (fichier XML) Extrait du descripteur de déploiement généré (fichier XML) <ejb-jer> <enterprise-beans> <entity> <ejb-name>AdherentEJB </ejb-name> <home>AdherentHome </home> <remote>Adherent </remote> <persistance-type>Container </persistance-type> <primary-key-class>java.lang.String </primary-key-class> <cmp-field> <field-name>nom </field-name> </cmp-field> <query> <method-name>findByNom</method-name> <ejb-ql>SELECT DISTINCT OBJECT(p) … </query> <method> <method-name>getPrenom … Benoît Charroux - Entity Beans - Mars 00 - 31 Benoît Charroux - Entity Beans - Mars 00 - 32 16 Les associations • les associations (leurs navigabilités et leurs multiplicités) entre composants peuvent être gérées : • automatiquement pour les container-managed-persistent beans ; • par le développeur pour les bean-managed-persistent beans. La gestion des associations entre composants • Associations possibles : • de 1 vers 1 ; • de 1 vers n ; • de n vers 1 ; • de n vers n ; • Uni-directionnelles ou bi-directionnelle. Benoît Charroux - Entity Beans - Mars 00 - 34 17 Exemple d’une Association bidirectionnelle de 1 vers n Préciser les associations lors du déploiement public abstract class ExemplaireEJB implements EntityBean{ // … public abstract Adherent getAdherent(); public abstract void setAdherent( Adherent adherent ); } public abstract class AdherentEJB implements EntityBean{ // … public abstract Collection getExemplaires(); public abstract void setExemplaires( Collection exemplaires ); } Benoît Charroux - Entity Beans - Mars 00 - 35 Benoît Charroux - Entity Beans - Mars 00 - 36 18 Le cycle de vie d’un entity bean • Le cycle de vie est géré par le conteneur. A l’état poolé, tous les composants sont identiques Le cycle de vie d’un entity bean Le client invoque la méthode create Le conteneur invoque la méthode ejbActivate • Cas des bean-managed persistence : quand un composant passe à l’état prêt, le conteneur ne fixe pas une clef primaire (c’est aux méthodes ejbCreate et ejbActivate de le faire). Benoît Charroux - Entity Beans - Mars 00 - 38 19 Le cycle de vie d’un entity bean Le cycle de vie d’un entity bean • La méthode ejbCreate est appelée par le conteneur sur appel de la méthode create par le client : • pour un bean managed persistence, elle retourne une clef primaire et insère les champs sérializables dans une base de données ; • ses arguments doivent être compatibles avec RMI ; • elle ne peut être ni static, ni final ; • chaque méthode ejbCreate doit avoir une méthode ejbPostCreate associée. • La méthode ejbPostCreate est souvent vide mais elle peut appeler des méthodes de EntityContext, elle ne retourne rien. • La méthode ejbRemove est appelée automatiquement quand un client appelle la méthode remove, elle peut servir à supprimer l’état d ’un composant dans une base de donnée pour les bean managed persistence. Benoît Charroux - Entity Beans - Mars 00 - 39 Benoît Charroux - Entity Beans - Mars 00 - 40 20 Activation d’un container-managed persistence Activation d’un bean-managed persistence Benoît Charroux - Entity Beans - Mars 00 - 41 Benoît Charroux - Entity Beans - Mars 00 - 42 21 Synchronisation d’un container-managed persistence Synchronisation d’un bean-managed persistence Benoît Charroux - Entity Beans - Mars 00 - 43 Benoît Charroux - Entity Beans - Mars 00 - 44 22 Synchroniser l’état d’un composant avec une base de données • Les méthodes ejbLoad et ejbStore sont appelées automatiquement par le conteneur pour synchroniser l’état d’un composant avec la base de données ; • par exemple ejbLoad est appelée au début d’une transaction ; • pour un bean managed persistence, elle peuvent servir à charger (select en SQL) ou mémoriser (update en SQL) un état dans une base de données. Localiser un composant Benoît Charroux - Entity Beans - Mars 00 - 45 23 Localiser un composant • Pour localiser un composant, un client appelle une méthode find… • Les méthodes find… doivent être placées dans l’interface locale ; • cas des bean managed persistence : • il doit y avoir autant de méthode ejbFind… que de méthodes find… dans la classe du composant ; • les méthodes ejbFind… sont appelées automatiquement par un client lorsqu’il appelle find… ; Comparaison et référence des composants • il faut implémenter au moins la méthode ejbFindByPrimaryKey. • le type de retour d’une méthode ejbFind… doit être un clef primaire ou une collection de clefs primaires. • Cas de container-managed persistence : • c’est l’utilitaire de déploiement qui impémente les méthodes ejbFind…, il faut juste préciser les clauses SQL where… Benoît Charroux - Entity Beans - Mars 00 - 47 24 Comparer deux entity beans Obtenir une référence sur un entity bean • Pour comparer 2 entity beans, on peut utiliser isIdentical : • this ne peut pas être utilisée car le bean est distant ; Account a, b ; if( a.isIdentical( b ) ){ • utiliser getEJBObject() : System.out.println( "Identical" ) ; } public class EJB implements SessionBean{ EntityContext context ; public void setEntityContext( EntityContext context ){ • on peut aussi comparer les clefs primaires : this.context = context ; Account a, b ; } String keyA = (String)a.getPrimaryKey() ; public void methode( Bean bean ){ bean.f( context.getEJBObject() ) ; String keyB = (String)b.getPrimaryKey() ; } if( key1.compareTo( key2) == 0 ){ System.out.println( "Identical" ) ; } Benoît Charroux - Entity Beans - Mars 00 - 49 } Benoît Charroux - Entity Beans - Mars 00 - 50 25 Le passage d’objets par valeur • Les Enterprise Beans sont des objets distants qui consomment des ressources et de la bande passante ; • Évitez de transmettre des Entity beans à un client => incohérence entre l’état du bean chez le client, et celui dans le serveur ; • Il est préférable de créer un objet sérializable quand un objet : Le passage par valeur • à des champs accessibles en lecture seule ; • est à granularité fine ; public class Adresse implements java.io.Serializable{ String adresse ; public Adresse( String adresse ){ this.adresse = adresse ; } public String getAdresse(){ return adresse ; } } • Faites interagir le client et les entity beans dans le serveur par l’intermédiaire de session beans. Benoît Charroux - Entity Beans - Mars 00 - 52 26