1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
21 22 23 24 25 26 27 28 29 30 31 32 33 

EJB 2 - Les Entreprise Java Bean (JavaBeans)

4.4.Spécifications d’un Entity Bean

4.4.1.Interfaces

        1. Home Interface

La home interface définit les méthodes create(), finder() et home().
          1. La méthode create

Chaque méthode create() dans la home interface doit répondre aux exigences suivantes :
  • Elle a le même nombre et type d'arguments que la méthode ejbCreate() correspondante dans la classe de l'enterprise bean.
  • Elle renvoie le type de la remote interface du bean.
  • La clause throws inclut les exceptions indiquées par la clause throws des méthodes ejbCreate() et ejbPostCreate() correspondantes.
  • La clause throws inclut javax.ejb.CreateException.
  • Si la méthode est définie dans une remote home interface (pas local home interface), alors la clause throws inclut java.rmi.RemoteException.
          1. Les méthodes Finder

Chaque méthode finder dans la home interface correspond à une méthode finder dans la classe de l'entity bean. Le nom d'une méthode finder dans la home interface commence par find, tandis que le nom correspondant dans la classe de l'entity bean commence par ejbFind. Par exemple, l’interface SavingsAccountHome définit la méthode findByLastName(), et la classe SavingsAccountBean implémente la méthode ejbFindByLastName(). Voici les règles pour définir les signatures des méthodes finder des home interfaces.
  • Le nombre et les types d'arguments doivent correspondre à ceux de la méthode correspondante dans la classe de l'entity bean.
  • Le type de retour est le type de la remote interface de l’entity bean, ou une collection de ces types.
  • Les exceptions de la clause throws incluent ceux de la méthode correspondante dans la classe de l'entity bean.
  • La clause throws contient javax.ejb.FinderException.
  • Si la méthode est définie dans une remote home interface, alors la clause throws inclut java.rmi.RemoteException.
          1. Les méthodes home

Chaque définition de méthode home dans la home interface correspond à une méthode dans la classe de l’entity bean. Dans l'interface home, le nom de méthode est arbitraire, à condition qu’il ne commence pas par create ou find. Dans la classe du bean, le nom de méthode correspondant commence par ejbHome. Par exemple, dans la classe SavingsAccountBean le nom est ejbHomeChargeForLowBalance(), mais dans l'interface SavingsAccountHome le nom est chargeForLowBalance().

La signature de la méthode home doit suivre les mêmes règles indiquées pour les méthodes de finder dans le chapitre précédent (sauf qu'une méthode home ne lève pas de FinderException).
        1. Remote Interface

La remote interface hérite de javax.ejb.EJBObject et définit les méthodes métiers qu'un client distant peut appeler.

Les conditions pour les définitions de méthode dans une remote interface sont les mêmes pour les session beans et les entity beans :
  • Chaque méthode dans la remote interface doit correspondre à une méthode de la classe de l'enterprise bean.
  • Les signatures des méthodes dans la remote interface doivent être identiques aux signatures des méthodes correspondantes de la classe de l'enterprise bean.
  • Les arguments et les valeurs de retour doivent être des types valides pour RMI.
  • La clause throws doit inclure java.rmi.RemoteException.

Une interface locale a les mêmes conditions, aux exceptions près suivantes :
  • Les arguments et les valeurs de retour ne sont pas obligés d’être valides pour RMI.
  • La clause throws n'inclut pas java.rmi.RemoteException.


4.4.2.Classe du Bean

L’interface EntityBean hérite de l’interface EnterpriseBean, qui hérite de l’interface Serializable. L’interface EntityBean déclare plusieurs méthodes, telles que ejbActivate() et ejbLoad(), que vous devez implémenter dans la classe de votre entity bean. Ces méthodes seront vues en détail dans les chapitres qui suivent.

        1. BMP (Bean Managed Persistance)

La classe de l’entity bean de notre exemple s’appelle SavingAccountBean. Elle doit répondre aux exigeances de n’importe quel entity bean BMP. Tout d’abord elle implémente les points suivants :
  • L’interface EntityBean
  • Zero ou plus méthodes ejbCreate() et ejbPostCreate()
  • Des méthodes finder
  • Des méthodes métiers
  • Des méthodes home

En plus, une classe d’entity bean BMP répond aux exigeances suivantes :
  • La classe est déclarée public
  • Elle ne peut être abstract ou final
  • Elle contient un constructeur vide
  • Elle n’implémente pas de méthode finalize()

          1. La méthode ejbCreate

Quand le client appele une méthode create(), le conteneur d’EJB appele la méthode ejbCreate() correspondante. Typiquement, une méthode ejbCreate() effectue les tâches suivantes :
  • Insère l’état de l’entité dans la base de données
  • Initialise les variables d’instances
  • Retourne la clé primaire

La méthode ejbCreate() de SavingAccountBean insere l’état de l’instance dans la base en appelant la méthode privée insertRow(), qui exécute la requête SQL INSERT.

Bien que la classe de SavingsAccountBean ait juste une méthode ejbCreate(), un enterprise bean peut contenir de multiples méthodes ejbCreate().

En écrivant une méthode ejbCreate() pour un entity bean, soyez sûr de suivre ces règles :
  • Le modificateur d’accès doit être public.
  • La valeur de retour doit être la clé primaire.
  • Les arguments doivent avoir un type adéquat à l’API Java RMI.
  • Les modificateurs de la méthode ne peuvent être final ou static.

La clause throws peut inclure javax.ejb.CreateException et les exceptions qui sont spécifiques à votre application. Une méthode ejbCreate() génère habituellement une CreateException si un paramètre n’est pas valide. Si la méthode ne peut créer une entité parcequ’une autre entité avec la même clé primaire existe déjà, elle devrait générer une javax.ejb.DuplicateKeyException (une sous-classe de CreateException). Si un client reçoit une CreateException ou une DuplicateKeyException, il devrait supposer que l'entité n’a pas été créée.

L’état d'un entity bean peut être directement inséré dans la base de données par n’importe quelle application (même inconnue par le serveur J2EE). Par exemple, un script SQL pourrait insérer une ligne dans la table savingsaccount. Bien que l'entity bean pour cette ligne n’ait pas été créé par une méthode ejbCreate(), le bean peut être utilisé par un programme client.
          1. La méthode ejbPostCreate

Pour chaque méthode ejbCreate(), vous devez écrire une méthode ejbPostCreate() dans la classe de l'entity bean. Le conteneur d’EJB appelle ejbPostCreate() juste après l’appel d’ejbCreate(). A la différence de la méthode ejbCreate(), la méthode ejbPostCreate() peut appeler les méthodes getPrimaryKey() et getEJBObject() de l’interface EntityContext. Souvent, vos méthodes ejbPostCreate() seront vides.

La signature d'une méthode ejbPostCreate() doit répondre aux exigences suivantes :
  • Le nombre et le type des arguments doivent correspondre à une méthode ejbCreate() correspondante.
  • Le modificateur d’accès doit être public.
  • Les modificateurs de la méthode ne peuvent être final ou static.
  • Le type de retour doit être void.
La clause throws peut inclure javax.ejb.CreateException et les exceptions qui sont spécifiques à votre application.
          1. La méthode ejbRemove

Un client supprime un entity bean en appelant la méthode remove(). Cette invocation provoque l’appel de ejbRemove() par le conteneur d’EJB, qui supprime l’état de l’entité de la base de données. Dans la classe SavingsAccountBean, la méthode ejbRemove() appelle une méthode privée appelée deleteRow(), qui exécute la requête SQL DELETE.

Si la méthode ejbRemove() rencontre un problème système, elle devrait lever une javax.ejb.EJBException. Si elle rencontre une erreur d’application, elle devrait lever une javax.ejb.RemoveException.

Un entity bean peut également être supprimé directement par une suppression dans la base de données. Par exemple, si un script SQL supprime une ligne qui contient un état d'un entity bean, alors cet entity bean est supprimé.
          1. Les méthodes ejbLoad et ejbStore

Si le conteneur à besoin de synchroniser les variables d'instance d'un entity bean avec les valeurs correspondantes stockées dans la base de données, il appelle les méthodes ejbLoad() et ejbStore(). La méthode ejbLoad() régénère les variables d'instance de la base de données, et la méthode ejbStore() écrit les variables dans la base de données. Le client peut ne pas appeler ejbLoad() et ejbStore().

Si une méthode métier est associée à une transaction, le conteneur appelle ejbLoad() avant que la méthode soit exécutée. Juste après que la méthode soit exécutée, le conteneur appelle ejbStore(). Puisque le conteneur appelle ejbLoad() et ejbStore(), vous ne devez pas régénérer et stocker les variables d’instance dans vos méthodes métiers. La classe SavingsAccountBean compte sur le conteneur pour synchroniser les variables d'instance avec la base de données. Par conséquent, les méthodes métiers de SavingsAccountBean devraient être associées aux transactions.

Si les méthodes ejbLoad() et ejbStore() ne peuvent pas localiser une entité dans la base de données, elles devraient lever une javax.ejb.NoSuchEntityException. Cette exception est une sous-classe d'EJBException. Puisqu'EJBException est une sous-classe de RuntimeException, vous ne devez pas l’inclure dans la clause throws. Quand une NoSuchEntityException est générée, le conteneur d’EJB l'englobe dans une RemoteException avant de la renvoyer au client.

Dans la classe SavingsAccountBean, ejbLoad() appelle la méthode loadRow(), qui exécute la reqûete SQL SELECT et assigne les données récupérées aux variables d'instance. La méthode ejbStore() appelle la méthode storeRow(), qui stocke les variables d'instance dans la base de données avec une requête SQL UPDATE.
          1. Les méthodes Finder

Les méthodes finder permettent aux clients de charger les entity beans. L’application SavingAccountClient utilise trois méthodes finder : findByPrimaryKey(), findByLastName(), findInRange().

Pour chaque méthode finder disponible pour le client, la classe de l’entity bean doit implémenter une méthode correspondante dont le nom a le préfixe ejbFind. Les méthodes finder qui sont spécifiques à votre application, telles que findByLastName() et findInRange(), sont optionnelles. En revanche, la méthode ejbFindByPrimaryKey() est obligatoire. Comme son nom l’indique, elle prend pour argument la clé primaire, qui est utilisé pour localiser un entity bean. Dans la classe SavingAccountBean, la clé primaire est la variable id.

La méthode ejbFindByPrimaryKey() peut vous sembler étrange, parce qu'elle utilise une clé primaire comme paramètre et valeur de retour. Cependant, rappelez-vous que le client n’appelle pas la méthode ejbFindByPrimaryKey() directement. C'est le conteneur qui appelle cette méthode. Le client appelle la méthode de findByPrimaryKey(), qui est définie dans la home interface. La liste suivante récapitule les règles pour les méthodes finder que vous appliquez dans une classe d'entity bean BMP :
  • La méthode ejbFindByPrimaryKey() doit être implémentée.
  • Une méthode finder doit avoir son nom qui commence par ejbFind.
  • Le modificateur d’accès doit être public.
  • Les modifiacteurs de la méthode ne peuvent être final ou static.
  • Les paramètres et valeurs de retour doivent d’un type adéquat à l’API Java RMI (cette condition s'applique seulement aux méthodes définies dans une remote home interface et non local home interface).
  • Le type de retour doit être celui de la clé primaire ou une collection de clés primaires.

La clause throws peut inclure javax.ejb.FinderException et les exceptions spécifiques à votre application. Si une méthode finder retourne une seule clé primaire et que l'entité demandée n’existe pas, la méthode devrait lever une javax.ejb.ObjectNotFoundException (une sous-classe de FinderException). Si une méthode finder renvoie une collection de clés primaires et qu’elle ne trouve aucun objet, elle devrait renvoyer une collection vide.
          1. Les méthodes métiers

Les méthodes métiers contiennent la logique métier que vous voulez encapsulez dans l’entity bean. Habituellement, les méthodes métiers n’accèdent pas à la base de données, vous permettant de séparer la logique métier du code d’accès aux bases de données.

Les conditions pour la signature d’une méthode métier sont les mêmes pour les session beans et les entity beans :
  • Le nom de méthode ne doit pas être en conflit avec un nom de méthode défini par l'architecture EJB. Par exemple, vous ne pouvez pas appeler une méthode ejbCreate() ou ejbActivate().
  • Le modificateur d'accès doit être public.
  • Le modificateur de méthode ne peut pas être final ou static.
  • Les arguments et les types de retour doivent être des types adéquats pour l’API Java RMI. Cette condition s'applique seulement aux méthodes définies dans une remote home interface.

La clause throws peut inclure les exceptions que vous définissez pour votre application. La méthode debit(), par exemple, génère une InsufficientBalanceException. Pour indiquer un problème au niveau système, une méthode métier devrait lever une javax.ejb.EJBException.
          1. Les méthodes home

Une méthode home contient la logique métier qui s'applique à tous les entity beans d'une classe particulière. En revanche, la logique dans une méthode métier s’applique à un seul entity bean, une instance avec une identité unique. Lors d’un appel d’une méthode home, l’instance n'a pas d’identité unique ni d’état qui représente un objet métier. En conséquence, une méthode home ne doit pas accéder à l'état persistant du bean (variables d'instance). Pour un CMP, une méthode home ne doit pas non plus accéder à des relations.

Typiquement, une méthode home localise une collection d'instances de bean et appelle les méthodes métiers pendant qu'elle itère dans la collection. Cette approche est adoptée par la méthode ejbHomeChargeForLowBalance() de classe de SavingsAccountBean. Cette méthode applique des frais administratifs à tous les comptes d’épargne ayant un solde inférieur à une quantité indiquée. La méthode localise ces comptes en appelant la méthode findInRange(). Pendant qu'elle itère dans la collection d'instances de SavingsAccount, la méthode ejbHomeChargeForLowBalance() vérifie le solde et appelle la méthode métier debit().

Dans la classe d’entity bean, l’implémentation d’une méthode home doit appliquer ces règles :
  • Un nom de méthode home doit commencer par le préfixe ejbHome.
  • Le modificateur d’accès doit être public.
  • Le modificateur de méthode ne peut pas être static.

La clause throws peut inclure les exceptions qui sont spécifiques à votre application ; elle ne doit pas lever de java.rmi.RemoteException.
          1. Les appels à la base de données

Le Tableau ci-dessous récapitule les appels aux bases de données de la classe SavingsAccountBean. Les méthodes métiers de la classe SavingsAccountBean sont absentes parce qu'elles n'accèdent pas à la base de données. Au lieu de cela, ces méthodes métiers mettent à jour les variables d’instance, qui sont écrites dans la base de données quand le conteneur appelle ejbStore(). Un autre développeur pourrait avoir choisi d’accéder à la base de données dans les méthodes métiers de la classe SavingsAccountBean. Ce choix est une des décisions de conception qui dépendent des besoins spécifiques de votre application.

Méthode
Requête SQL
ejbCreate
INSERT
ejbFindByPrimaryKey
SELECT
ejbFindByLastName
SELECT
ejbFindInRange
SELECT
ejbLoad
SELECT
ejbRemove
DELETE
ejbStore
UPDATE
Les requêtes SQL de SavingAccountBean

          1. Clé primaire pour la BMP

Vous spécifiez la classe de la clé primaire dans le descripteur de déploiement de l’entity bean. Dans la plupart des cas, votre classe de clé primaire sera un String, un Integer, ou une autre classe qui appartient aux bibliothèques standards de J2SE ou de J2EE. Pour quelques entity beans, vous devrez définir votre propre classe de clé primaire. Par exemple, si le bean a une clé primaire composée (c'est-à-dire, composée de plusieurs champs), alors vous devez créer une classe de clé primaire.
            1. Classe de clé primaire

La classe de clé primaire suivante est une clé composée : les champs productId et vendorId, ensemble uniquement, identifient un entity bean.

public class ItemKey implements java.io.Serializable {

public String productId;
public String vendorId;

public ItemKey() {};

public ItemKey(String productId, String vendorId) {
this.productId = productId;
this.vendorId = vendorId;
}

public String getProductId() {
return productId;
}

public String getVendorId() {
return vendorId;
}

public boolean equals(Object other) {
if (other instanceof ItemKey) {
return (
productId.equals(((ItemKey) other).productId)
&& vendorId.equals(((ItemKey) other).vendorId));
}
return false;
}

public int hashCode() {
return productId.concat(vendorId).hashCode();
}
}

Pour la persistance gérée par le bean (BMP), une classe de clé primaire doit répondre aux conditions suivantes :
  • Le modificateur d’accès de la classe est public.
  • Tous les champs sont déclarés public.
  • La classe possède un constructeur public par défaut.
  • La classe implémente les méthodes hashCode() et equals(Object other).
  • La classe est sérialisable.
            1. Clés primaires dans la classe entity bean

Avec la persistance gérée par le conteneur, la méthode ejbCreate() assigne les paramètres d’entrée aux variables d’instance et ensuite retourne la classe de clé primaire :

public ItemKey ejbCreate(String productId, String vendorId,
String description) throws CreateException {
if (productId == null || vendorId == null) {
throw new CreateException("The productId and vendorId are required.");
}
this.productId = productId;
this.vendorId = vendorId;
this.description = description;
return new ItemKey(productId, vendorId);
}

La méthode ejbFindByPrimaryKey() vérifie l’existence dans le base de données d’une ligne pour la clé primaire passé en paramètre :

public ItemKey ejbFindByPrimaryKey(ItemKey primaryKey) throws FinderException {
try {
if (selectByPrimaryKey(primaryKey))
return primaryKey;
...
}

private boolean selectByPrimaryKey(ItemKey primaryKey)
throws SQLException {
String selectStatement =
"select productid "
+ "from item where productid = ? and vendorid = ?";
PreparedStatement prepStmt = con.prepareStatement(selectStatement);
prepStmt.setString(1, primaryKey.getProductId());
prepStmt.setString(2, primaryKey.getVendorId());
ResultSet rs = prepStmt.executeQuery();
boolean result = rs.next();
prepStmt.close();
return result;
}

            1. Récupérer la clé primaire

Un client peut chercher la clé primaire d'un entity bean en appelant la méthode de getPrimaryKey() de la classe EJBObject :

SavingsAccount account;
...
String id = (String)account.getPrimaryKey();

L’entity bean recherche sa propre clé primaire en appelant la méthode getPrimaryKey() de la classe EntityContext :

EntityContext context;
...
String id = (String) context.getPrimaryKey();


        1. CMP (Container Managed Persistance)

Un entity bean avec une persistance gérée par le conteneur offre d’importants avantages au développeur. D'abord, le conteneur d'EJB s’occupe de toutes les manipulations de stockage et de récupération dans la base de données. En second lieu, le conteneur gère les relations entre les entity beans. En raison de ces services, vous n’avez pas à coder les accès aux bases de données dans l'entity bean. Au lieu de cela, vous spécifiez des paramètres dans le descripteur de déploiement du bean. Non seulement cette approche vous fait gagner du temps, mais elle rend le bean portable à travers divers serveurs de base de données.

Le code de la classe de l’entity bean doit répondre aux exigences syntaxtiques de la persistance gérée par le conteneur. D’abord, la classe doit être définie en public et abstract. En second lieu, la classe doit implémenter ce qui suit :
  • L’interface EntityBean
  • Zero ou plus méthodes ejbCreate() et ejbPostCreate()
  • Les méthodes d’accès get et set, définies en abstract, pour les champs persistants et relationels
  • Les méthodes select, définies en abstract
  • Les méthodes home
  • Les méthodes métiers

La classe de l’entity bean ne doit pas implémenter ces méthodes :
  • Les méthodes finder
  • La méthode finalize()

          1. Méthodes d’accès

Un entity bean CMP a des champs persistants et relationnels. Ces champs sont virtuels, ainsi vous ne les codez pas dans la classe comme variables d'instance. Au lieu de cela, vous les spécifiez dans le descripteur de déploiement du bean. Pour permettre l'accès à ces champs, vous définissez des méthodes abstraites get et set dans la classe de l'entity bean.

Méthodes d’accès pour les champs persistants
Le conteneur d’EJB effectue automatiquement la sauvegarde et la récupération des champs persistants du bean dans la base de données. Le descripteur de déploiement de PlayerEJB indique les champs persistants suivants :
  • playerId (clé primaire)
  • name
  • position
  • salary

Le nom d'une méthode d'accès commence par get ou set, suivi du nom du champ persistant ou relationnel avec sa première lettre en majuscule. Par exemple, les méthodes d'accès pour le champ salary sont getSalary() et setSalary(). Cette convention d’appellation est semblable à celle des composants JavaBeans.

Méthodes d’accès pour les champs relationnels
Dans l’application RosterApp, puisqu’un joueur peut appartenir à plusieurs équipes, une instance de PlayerEJB peut être lié à de nombreuses instances de TeamEJB. Pour indiquer cette relation, le descripteur de déploiement de PlayerEJB définit un champ relationnel appelé teams. Dans la classe PlayerBean, les méthodes d’accès pour le champ relationnel teams sont définies de la manière suivante :

public abstract Collection getTeams();
public abstract void setTeams(Collection teams);
          1. Méthodes finder et select

Les méthodes finder et select utilisent les requêtes EJB QL pour retourner les objets et les informations d’état des entity beans utilisant la persistance gérée par le conteneur.

Une méthode « select » est similaire à une méthode finder sur les points suivants :
  • Une méthode select peut retourner une interface locale ou distante (ou une collection d’interface).
  • Une méthode select interoge la base de donnée.
  • Le descripteur de déploiement spécifie une requête EJB QL pour une méthode select.
  • La classe de l’entity bean n’implémente pas les méthodes select.

Cependant, une méthode « select » diffère de manière significative d'une méthode finder :
  • Une méthode select peut renvoyer un champ persistant (ou une collection) d'un entity bean relatif. Une méthode finder peut renvoyer seulement une interface locale ou distante (ou une collection d'interfaces).
  • Puisqu'elle n’est exposée dans aucune des interfaces locales ou distantes, une méthode select ne peut pas être appelée par un client. Elle peut seulement être appelée par les méthodes implémentées à l’intérieur de la classe de l’entity bean. Une méthode select est habituellement appelée par des méthodes métiers ou home.
  • Une méthode select est définie dans la classe de l'entity bean. Pour la persistance gérée par le bean, une méthode finder est définie dans la classe de l'entity bean, mais pas pour la persistance gérée par le conteneur.

La classe PlayerBean définit ces méthodes « select » :

public abstract Collection ejbSelectLeagues(LocalPlayer player)
throws FinderException;
public abstract Collection ejbSelectSports(LocalPlayer player)
throws FinderException;

La signature pour une méthode « select » doit suivre ces règles :
  • Le préfixe du nom de la méthode doit être ejbSelect.
  • Le modificateur d’accès doit être public.
  • La méthode doit être déclarée abstract.
  • La clause throws doit inclure javax.ejb.FinderException.

          1. Méthodes métiers

Puisque les clients ne peuvent pas appeler de méthodes select, la classe PlayerBean les enveloppe dans les méthodes métiers getLeagues() et getSports() :

public Collection getLeagues() throws FinderException {
LocalPlayer player = (team.LocalPlayer) context.getEJBLocalObject();

return ejbSelectLeagues(player);
}

public Collection getSports() throws FinderException {
LocalPlayer player = (team.LocalPlayer) context.getEJBLocalObject();

return ejbSelectSports(player);
}
          1. Méthodes de l’Entity Bean

Puisque le conteneur manipule la persistance, les méthodes du cycle de vie dans la classe PlayerBean sont presque vides.

La méthode ejbCreate() initialise l’instance du bean en assignant les paramètres d'entrée aux champs persistants. À la fin de la transaction qui contient la demande de création, le conteneur insère une ligne dans la base de données. Voici le code source pour la méthode ejbCreate() :

public String ejbCreate(String id, String name, String position,
double salary) throws CreateException {

Debug.print("PlayerBean ejbCreate");
setPlayerId(id);
setName(name);
setPosition(position);
setSalary(salary);

return null;
}

La méthode ejbPostCreate() renvoie void et elle a les mêmes paramètres d'entrée que la méthode ejbCreate(). Si vous voulez placer un champ relationnel pour initialiser l'instance du bean, vous devriez le faire dans la méthode ejbPostCreate(). Vous ne pouvez pas initialiser un champ relationnel dans la méthode ejbCreate().

Excepté pour faire du debug, la méthode ejbRemove() de la classe PlayerBean est vide. Le conteneur appelle ejbRemove() avant de supprimer l'objet.

Le conteneur synchronise automatiquement l’état de l'entity bean avec la base de données. Après que le conteneur ait chargé l’état du bean depuis la base de données, il appelle la méthode ejbLoad(). De la même manière, avant de stocker l’état dans la base de données, le destinataire appelle la méthode ejbStore().

4.4.3.Descripteur de déploiement

Le descripteur de déploiement pour les BMP est bien moins important que pour les CMP. En effet, les Enity CMP étant géré en très grande partie par le container, il faut obligatoirement déclarer plus d’informations que pour le cas des BMP.
        1. BMP

Voici un exemple de descripteur de déploiement concernant un Entity BMP :


<entity >
<description><![CDATA[Description for ShopUser]]></description>
<display-name>Name for ShopUser</display-name>

<ejb-name>ShopUser</ejb-name>

<local-home>ejb.shopuser.ShopUserLocalHome</local-home>
<local>ejb.shopuser.ShopUserLocal</local>

<ejb-class>ejb.shopuser.ShopUserBean</ejb-class>
<persistence-type>Bean</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
</entity>


Nous retrouvons, ici, une déclaration d’entity très basique.
        1. CMP

À l’opposé, les Entity CMP doivent déclarer l’ensemble des champs persistants et relationnels. De ce fait, la description de l’entity sera plus importante.
Voici un exemple de descripteur pour un Entity CMP :


<entity >
<description><![CDATA[Description for ProductFamily]]></description>
<display-name>Name for ProductFamily</display-name>

<ejb-name>ProductFamily</ejb-name>

<local-home>com.society.stockmanager.interfaces.ProductFamilyLocalHome
</local-home>
<local>com.society.stockmanager.interfaces.ProductFamilyLocal</local>

<ejb-class>com.society.stockmanager.ejb.ProductFamilyBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>ProductFamily</abstract-schema-name>
<cmp-field >
<description><![CDATA[Getter for CMP Field code]]></description>
<field-name>code</field-name>
</cmp-field>
<cmp-field >
<description><![CDATA[Getter for CMP Field description]]></description>
<field-name>description</field-name>
</cmp-field>
<primkey-field>code</primkey-field>

<query>
<query-method>
<method-name>findAll</method-name>
<method-params>
</method-params>
</query-method>
<result-type-mapping>Local</result-type-mapping>
<ejb-ql><![CDATA[select Object(p) from ProductFamily p]]></ejb-ql>
</query>
</entity>



<relationships>
<ejb-relation>
<ejb-relation-name>products-providers</ejb-relation-name>
<ejb-relationship-role >
<ejb-relationship-role-name>providers-products
</ejb-relationship-role-name>
<multiplicity>Many</multiplicity>
<relationship-role-source >
<ejb-name>Provider</ejb-name>
</relationship-role-source>
<cmr-field >
<cmr-field-name>products</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>
</ejb-relationship-role>

<ejb-relationship-role >
<ejb-relationship-role-name>products-providers
</ejb-relationship-role-name>
<multiplicity>Many</multiplicity>
<relationship-role-source >
<ejb-name>Product</ejb-name>
</relationship-role-source>
<cmr-field >
<cmr-field-name>providers</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>
</ejb-relationship-role>

</ejb-relation>
</relationships>


Nous pouvons maintenant remarquer que l’ensemble des champs persistants et des requêtes ejb-ql (cf. chapitre EJB-QL) est déclaré entre les balises « entity ». Les relations (champs relationnels) sont déclarées entre les balises « relationships » et « ejb-relation ».

4.4.4.Cycle de vie

Le schéma ci-dessous montre les étapes par lesquelles passe un entity bean durant sa vie. Après que le conteneur d’EJB a créé l’instance, il appelle la méthode setEntityContext() de la classe de l’entity bean. Cette méthode passe l’EntityContext au bean.

Après l’instanciation, l’entity bean est déplacé vers un pool d’instances disponibles. A cette étape (pooled), l’instance n’est associée à aucune identité d’EJB particulière. Toutes les instances dans le pool sont identiques. Le conteneur d’EJB assigne une identité à une instance quand elle passe à l’état ready.

Il existe deux façons de passer de l’état pooled à l’état ready. Soit le client appelle la méthode create(), provoquant l’appel des méthodes ejbCreate() et ejbPostCreate() par le conteneur, soit le conteneur appelle la méthode ejbActivate(). A l’état ready, les méthodes métiers de l’entity bean peuvent être appelées.

Il existe également deux manières de passer de l’état ready à l’état pooled. La première : un client peut appeler la méthode remove(), qui provoque l’appel de la méthode ejbRemove() par le conteneur. La seconde : le conteneur d’EJB peut appeler la méthode ejbPassivate().

Cycle de vie d’un Entity Bean

A la fin du cycle de vie, le conteneur d’EJB supprime l’instance du pool et appelle la méthode unsetEntityContext().

Dans l’état pooled, une instance n’est associée à aucune identité d’EJB particulière. Avec la bean-managed persistence, quand le conteneur d’EJB déplace une instance de l’état pooled à l’état ready, il n’affecte pas automatiquement la clé primaire. Par conséquent, les méthodes ejbCreate() et ejbPostCreate() doivent assigner une valeur à la clé primaire. Si la clé primaire est incorrecte, les méthodes ejbLoad() et ejbStore() ne peuvent synchroniser les variables d’instances avec la base de données.

4.4.5.Différence entre BMP et CMP

Puisqu’il ne contient aucun accès à la base de données, un CMP entity bean nécessite beaucoup moins de code qu’un BMP. Par exemple, le fichier source PlayerBean.java est beaucoup plus léger que celui vu au chapitre précédent SavingAccountBean.java. Le tableau 5-2 compare les codes des deux types d’entity beans.

Différence
Container-Managed
Bean-Managed
Définition de la classe
Abstract
Not abstract
Accès à la base de données
Géré par le conteneur
Codé par le développeur
Etat persistant
Representé par des champs persistants virtuels
Codé comme variables d’instance
Méthodes d’accès aux champs persistants et relationnels
Requises
Aucune
Méthode findByPrimaryKey
Gérée par le conteneur
Codé par le développeur
Méthodes finder personnalisés
Gérée par le conteneur, mais le développeur doit écrire les requêtes EJB QL
Codé par le développeur
Méthodes select
Gérées par le conteneur
Aucune
Valeur de retour de ejbCreate
null
Doit être la clé primaire
Différence de code entre les deux types persistance

On notera que pour les deux types de persistance, les règles à appliquer pour les méthodes métiers et home sont les mêmes.



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
21 22 23 24 25 26 27 28 29 30 31 32 33 

Retrouvez ci-dessous les autres sections du Laboratoire Sun
Exemples de code
JavaManipuler les looks and feel (lister et affecter)10/15/07
JavaFaire sa propre injection de dépendance avec les annotations5/9/06
JavaSplash screen avec progress Bar5/5/06
JavaFaire un splash screen en swing5/5/06

Essentiels de cours Java
</
JavaEJB 3 - Les Entreprise Java Bean version 3 (JavaBeans)
Cet essentiel est la suite de « Entreprise JavaBean 2.1 ». Cependant, nous allons étudier les nouvelles spécifications 3.0 qui simplifient énormément le développement par rapport aux EJB 2.6/20/06
JavaSWT - Créer des interfaces graphiques performantes
SWT (Standard Widget Toolkit) est une librairie graphique qui vous permet de réaliser des applications graphiques Java beaucoup plus avancées et surtout plus rapide à l’exécution.1/29/06
JavaStruts - Un framework MVC pour vos applications J2EE
Struts est un framework open-source qui vous permet de gagner du temps, mais qui permet aussi de voir des applications complexes comme une suite de composants de base : Vues, Actions, Modèles. Vous gagnez ainsi en évolutivité et en lisibilité du code.1/13/06
JavaHibernate - Persistance objet - relationnel
Cet essentiel explique comment utiliser Hibernate afin de gérer la persistance objet relationnel au sein de vos applications Java.12/14/05
JavaIntroduction J2EE - Applications d'entreprise
Cours d'introduction aux diverses technologies et outils que l'on peut rencontrer dans le monde du Java orienté entreprise J2EE12/14/05
JavaEJB 2 - Les Entreprise Java Bean (JavaBeans)
L'objectif avec EJB2 (Entreprise JavaBeans) est d'introduire les concepts de l’Ingénierie Logicielle Basée sur les Composants.12/14/05
JavaDesign Pattern - Améliorez l'architecture de vos programmes
Afin de répondre a des situation récurrentes en programmation, les "design pattern" apportent une solution type à beaucoup de contraintes liées à la programmation objet.12/14/05
JavaArchitecture J2EE - Comment organiser son application J2EE
Ce cours explique comment créer un code modulable, lisible et évolutif afin d'assurer la pérénité de son application.12/14/05
JavaLes web-services - Publication de services
Le développement tend vers les technologies du Web. Il est difficile de faire la distinction entre les différents logiciels qui sont de plus en plus intégrés au Web. Les Web Services rentrent dans l’optique de différencier bien précisément les couches.12/14/05
JavaAnt - L'automatisation des tâches du programmeur
Ecrire des scripts afin d'exécuter les tâches récurrentes10/31/05
JavaIntroduction au langage Java - Présentation & historique
Présentation des origines du langage, ainsi que se buts premiers8/11/05
JavaLa Syntaxe Java - Bases & nomenclatures
Bases de la syntaxe du langage Java8/11/05
JavaLes Classes - Concepts & héritage
Base du développement objet en Java grâce aux classes8/11/05
JavaLes Exceptions - Gestion d'erreurs
Gérer les erreurs liés à la programmation8/11/05