4 C - Atelier EJB 3.0 avec NetBeans 5.5

chuckleelephantbutteSoftware and s/w Development

Jun 9, 2012 (4 years and 6 months ago)

927 views

Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 1/20

Atelier
4-C


Développement EJB 3.0 avec
NetBeans 5.5 et JBOSS






Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 2/20
Au cours de cette nous allons développer une petite application d’entreprise permettant de gérer les
comptes des clients d’une banque.
Cette application comprendra un module frontal Web et un module EJB comme le montre cette
capture prise lors de la création de notre Entreprise Application sur NetBeans:




Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 3/20
1) Le module EJB :

A présent occupons nous du module ejb :
Nous devons arriver à configurer notre base de données Bank (MySQL) sur notre serveur JBoss
créé précédemment.
Pour ce faire nous nous sommes appuyés sur les exemples fournis avec le serveur JBoss :
Nous avons copié le fichier mysql-ds.xml se trouvant dans l’exemple jca du répertoire
jboss\docs\exemples et l’avons collé dans le répertoire de déploiement \jboss\server\default\deploy
puis nous avons configuré le fichier en question avec les paramètres de notre base:

<datasources>
<local-tx-datasource>
<jndi-name>MysqlbankDS</jndi-name>
<connection-url> jdbc:mysql://localhost:3306/bank
</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password></password>
<exception-sorter-class-name>
org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter
</exception-sorter-class-name>
<!-- ... -- >
<!-- sql to call when connection is created
<new-connection-sql>some arbitrary sql</new-connection-
sql>
-->
<!-- ... -->
<!-- corresponding type-mapping in the standardjbosscmp-
jdbc.xml -->
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>

Dans ce fichier de
configuration nous avons
defini :
 MysqlbankDS comme
nom du jndi
la connexion url :
jdbc:mysql://localhost:3306/
bank
Ainsi que le nom de
l’utilisateur et son password

Sans oublier de mettre le mysql-connector dans le repertoire

\jboss\server\default\lib pour pouvoir se
connecter et gérer notre base de données MySQL.
Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 4/20
Revenons sur NetBeans pour générer les Entity Classes à partir de notre base de données Bank
comme suit :
Clic droit sur le module EJB new=>Entity Classes From Database





A ce niveau nous pouvons soit
choisir la data source si nous
l’avons déjà utilisé
précédemment ce qui est notre
cas soit créer une nouvelle en
configurant une nouvelle
connexion.

Par la suite sélectionner les
tables à partir desquelles nous
voudrions générer des entity
beans.

Et cliquer sur Next pour
continuer.







Nous voyons chaque entity,
qui va être créée, associée à
la table de la base de
données à partir de laquelle
elle va être générée.

Avant de finir la création
des Entity avec Finish nous
devons créer le fichier
persistence.xml en cliquant
sur Create Persistence Unit.


Pour créer le fichier persistence.xml il
suffit de cliquer sur Create.
Attention le fichier généré
comporte une erreur dans cette balise:
<jta-datasource>MysqlbankDS
</jta-data-source>
Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 5/20


entrainera cette exception

javax.naming.NameNotFoundException
: MysqlbankDS not bound


Voici le fichier corrigé en préfixant notre Data Source par java:/ :

<persistence version="1.0"
xmlns="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="BanquePlusPlus-ejbPU" transaction-
type="JTA">
<jta-data-source>java:/MysqlbankDS</jta-data-source>
<properties/>
</persistence-unit>
</persistence>


Sans l’ajout de java:/ JBoss ne
reconnaît pas la Data Source

Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 6/20
Nous allons maintenant voir en détail le code de notre Entity bean :

package com.insat.ejb;

import java.io.Serializable;
import java.math.BigInteger;
import javax.persistence.*

@Entity
@Table(name = "transaction")
@NamedQueries( {
@NamedQuery(name = "Transaction.findByMontant", query = "SELECT t FROM
Transaction t WHERE t.montant = :montant"),
@NamedQuery(name = "Transaction.findByNumcompte", query = "SELECT t FROM
Transaction t WHERE t.numcompte = :numcompte"),
@NamedQuery(name = "Transaction.findByNumtransaction", query = "SELECT t
FROM Transaction t WHERE t.numtransaction = :numtransaction"),
@NamedQuery(name = "Transaction.findByType", query = "SELECT t FROM
Transaction t WHERE t.type = :type")
})

public class Transaction implements Serializable {

@Column(name = "Montant")
private Float montant;

@Column(name = "Num_compte")
private Integer numcompte;

@Id
@Column(name = "Num_transaction", nullable = false)
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer numtransaction;

@Column(name = "Type")
private String type;

public Transaction() {
}

public Transaction(Integer numtransaction) {
this.numtransaction = numtransaction;
}

/* Setters et getters */
}

Annotations de classe
• @Entity : déclare une classe
correspondant à un entity bean
(EB)
• @NameQuery : associe une
requêtre SQL à cet EB

Annotations d'attribut
• @Id : définit une clé primaire
• @Column: définit une colonne de la
DB
• @GeneratedValue : permet de
définir un attribut dont la valeur est
générée par le conteneur ( entier
auto-incrémenté)


Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 7/20
Nous allons maintenant modifier nos entity beans pour mettre en évidence la relation un à plusieurs
qui existe entre eux :



Côté Transaction :
public class Transaction implements Serializable {

private Compte compte;

public Transaction(Compte compte, Integer id) {
this.compte = compte;
this.id = id;
}

@ManyToOne
@JoinColumn(name="Num_compte")
public Compte getCompte() { return compte; }
public void setCompte(Compte compte) { this.compte = compte;}

/* . . . */
}


Côté Compte :

public class Compte implements Serializable {

private Collection<Transaction> transactions;


@OneToMany
public Collection<Transaction> getTransactions() { return transactions; }
private Collection<Transaction> transactions;
public void addTransaction( Integer id ) {
Transaction t = new Transaction(this,id);
getTransactions().add(t);
}
public void setTransactions( Collection<Transaction> transactions ) {
this.transactions = transactions;
}
/* . . . */
}
Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 8/20
Comment résoudre les nombreuses dépendances entre les clients et les beans ?
 Solution : présenter aux clients une seule interface façade (stateless session bean)



Passons maintenant à la création des Session Beans ce qui ne va pas prendre beaucoup de temps avec
NetBeans. Pour les ajouter, il suffit de cliquer avec le bouton droit sur le module EJB new => Session
Bean For Entity Classes.




Nous avons sélectionné
les trois classes dont
nous avons besoin.

Et nous continuons
avec Next.

Nous avons selectionné
l’interface Remote car
notre EJB sera utilisé
par une classe qui ne
réside pas dans notre
container EJB.

Et voila nous tenons notre module EJB, à part la petite erreur généré, NetBeans rend la création du
module EJB très simple.

Examinons notre TransactionFacade de plus près:
Design Pattern Facade


• traitements effectués par la façade minimaux
essentiellement délégation
• éventuellement plusieurs façades sur un même
ensemble de beans


Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 9/20

package com.insat.ejb;

import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class TransactionFacade implements TransactionFacadeRemote {

@PersistenceContext
private EntityManager em;

public TransactionFacade() {}
public void create(Transaction transaction) { m.persist(transaction);

}
public void edit(Transaction transaction) { em.merge(transaction); }
public void destroy(Transaction transaction) {
em.merge(transaction);
em.remove(transaction);


}
public Transaction find(Object pk) {
return (Transaction) em.find(Transaction.class, pk);


}
public List findAll() {
return em.createQuery("select object(o) from Transaction as
o").getResultList();

}
}

 L’appel de la méthode create de notre SessionFacade provoque l’appel de la méthode persist de
notre entity manager dès lors une entité « nouvelle » devient une entité gérée
 L’état de l’entité sera sauvegardé dans la BD au prochain flush ou commit
 Aucune instruction ne sera nécessaire pour faire enregistrer au moment du commit dans la base
de données les modifications effectuées sur l’entité par l’application ; en effet le Entity manager
conserve toutes les informations nécessaires sur les entités qu’il gère.

 La méthode remove(transaction) du entity manager supprime une tansaction gérée ainsi que les
données correspondantes de la base seront supprimées de la base au moment du flush du contexte
de persistance
 L’appel de la méthode find permet de faire une recherche selon la clé primaire. La recherche
est polymorphe : l'entité récupérée peut être de la classe passée en paramètre ou d'une sous-classe
(renvoie null si aucune entité n’a l’identificateur passé en paramètre
Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 10/20
Dans ce qui a précédé, nous avons construit nos entity beans à partir de la base de données.
Le chemin inverse peut être réalisé (construction des tables de la base de données à partir des
entities.
Nous avons fait un petit exemple de Module EJB illustrant cette procédure, ainsi que son
application cliente.


Contrairement à ce que nous avons fait précedemment nous allons créer une Entity class « vierge »
et non pas une Entity Class from DataBase


Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 11/20
Pendant la création de notre entity nous pouvons créer une unité de persistance qui aura comme
provider Hibernate et comme data Source MySQLbankDS (c’est une base de données MySQL qui
ne contient pour l’instant aucune table)



Notre Entity contiendra 5 champs : id (clé primaire), nom, prénom, num_compte et montant. (il ne
faut pas oublier de générer les accesseurs de nos attributs.



Nous allons maintenant créer une facade pour notre Entity : comme d’habitude il suffit de
séléctionner notre Entity (ClientBanque) et définir les interfaces qu’elle devra
implemnter(remote). Netbeans s’occupera de tout le reste.




Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 12/20



Nous allons maintenant nous intéresser à la partie cliente :



Voici le code de notre application cliente:

public static void main(String[] args) {
Main m = new Main();
ClientBanqueFacadeRemote cbfacade = m.lookupClientBanqueFacade();
ClientBanque cb = new ClientBanque();
cb.setNom("Ben Jrad"); cb.setPrenom("Mohamed"); cb.setNum_compte("a1");
cb.setMontant(1000);
cbfacade.edit(cb);
System.out.println("Enregistrement effectué");
}
Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 13/20
Nous avons importé les jars client :
Pour cela nous avons créé une nouvelle Library que nous avons nommé client et dans la quelle nous
avons importé tous les jars se trouvant dans jboss/client :



Maintenant il suffit d’importer notre nouvelle Library dans le module war :



Une fois notre application cliente executée nous pouvons voir que une table clientbanque a été
créée et que notre enregistrement a été inséré.


Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 14/20
2. Le module Web :
Nous avons implémenté notre module Web en utilisant le Framework JSF pour nous faciliter la tache.

Attention il ne faut pas ajouter le framework JSF à notre module web comme nous avons
l’habitude de faire (clic droit sur le module web > propriété> framework> JavaServerPages> Add)
En effet, il y a un problème d’incompatibilité entre la version du framework donné par Netbeans (JSF
1.1) et celui embedded dans JBoss (JSF1.2) !
L’ajout du framework d’une manière traditionnelle empêcherait le déploiement de notre module web
ultérieurement et pourrait déclencher cette erreur.

2007-11-10 00:01:17,974 ERROR
[org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/address]]
Exception sending context destroyed event to listener instance of class
org.jboss.web.jsf.integration.config.JBossJSFConfigureListener

 Pour pouvoir utiliser la nouvelle version de JSF qui existe déjà dans JBoss, nous serons contraints
à ne pas utiliser les wizards et donc de configurer nous même notre faces-config.xml et notre web.xml

Donc nous avons eu à faire deux choses à savoir :

• Les pages JSP de l’application





Ci contre les jsp créés à savoir une page
d’accueil, des formulaires de saisie, de
modification et d’affichage sans oublier des
pages d’erreur et de succès.

Ce sont des JSP qui interagissent pour la plus
part avec les managed bean pour les instancier
avec le contenu du formulaire le long de la
session.

Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 15/20
• Les Managed Bean :

Les manged Beans sont générés comme à notre habitude clic droit sur le module war New => JSF
Managed Bean, nous avons répété cette procédure trois fois pour générer nos managed Bean :

Clients

Comptes

Transactions
 Pour gérer le formulaire d’ajout de compte et de client

 Pour gérer le formulaire d’affichage de compte ainsi que le formulaire des
modifications des paramètres du client propriétaire de ce compte
 Pour gérer le formulaire des transactions

Prenons pour exemple la classe Transactions où nous avons géré le formulaire d’effectuation des
transactions :

public class Transactions {

private Integer numCompte;
private float montantTrans;

/** … */
}

Ce bean est associé au formulaire transaction
dans lequel il y a deux champs le numéro du
compte et le montant de la transaction.


Ne pas oublier les setters et getters.

Une fois les attributs de chaque beans déclarés nous allons nous intéressé aux méthodes à utiliser lors
de la validation du formulaire et spécialement du formulaire de Transaction :


public String debiter(){

}

public String crediter(){

}

Notre formulaire a deux boutons un pour
débiter et un pour créditer et chacun fait appel à
la méthode de son nom.

Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 16/20
Pour pouvoir exploiter les méthodes de nos bean se trouvant dans le module EJB nous devons créer
les méthodes lookup appropriées à chaque Session Bean.
Pour cela laissons NetBeans faire :





Clic droit sur la fenetre du managed Bean
Transactions et clic gauche sur Call
Entreprise Bean d’Entreprise Ressources

Nous avons par la suite choisi les
FacadeRemote des Entity dont nous avons
besoin dans notre cas :
-CompteFacadeRemote
-TransactionFacadeRemote
Dont voici le code generé ci-dessous :



private CompteFacadeRemote lookupCompteFacade() {
try {
Context c = new InitialContext();
return (CompteFacadeRemote)
c
.lookup("java:comp/env/ejb/CompteFacade");
}
catch(NamingException ne) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE,"exception
c
aught" ,ne);
throw new RuntimeException(ne);
}
}


Nous avons aussi généré de la même manière lookupTransactionFacade et lookupClientFacade pour
interagir avec les Entity Beans.

Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 17/20
Nous pouvons maintenant implémenter nos méthodes :

public void flush(){
setMontantTrans(0);
setNumCompte(new Integer(0)); }
public String debiter(){
CompteFacadeRemote compte =lookupCompteFacade();


Compte comt = compte.find(this.getNumCompte());


TransactionFacadeRemote transaction =
lookupTransactionFacade();


Transaction trans = new Transaction();


if (comt==null){return "introuvable";}
else { float solde = comt.getMontant();
if (getMontantTrans()>solde){
return "impossible";
}
else {
solde = solde - getMontantTrans();
comt.setMontant(solde);
trans.setMontant(getMontantTrans());
trans.setNumcompte(getNumCompte());
trans.setType("Debiter");
compte.edit(comt);


transaction.edit(trans);


this.flush();
return "effectuee";
}
}
}
public String crediter() {
/* Même principe * /
}


Nous avons défini une méthode flush() pour
chaque managed Bean pour vider ses attributs
après les avoir utiliser


Récupération de l’interface remote de notre
CompteFacade.


Instantiation des entity bean correspondant
au numéro de compte à travers la méthode find.











Enregistrement des modifications dans la base
de données à travers la méthode edit et plus
précisément par la méthode merge du entity
manager.


Nous avons évidemment implémenté les autres managed Beans gérant le reste des pages JSP.

Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 18/20
Nous avons déployé l’application et nous l’avons par la suite runner à première vue l’application
marche mais au moment de l’effectuation d’opérations mettant en œuvre un RemoteFacade on a
l’erreur 500 :




La source de ce problème se trouve dans les bouts de code générés par NetBeans car nous somme allé
voir au JNDI l’arborescence de nos composants deployés et nous n’avons trouvé notre bean qu’au
niveau du Global JNDI Namespace.



return (CompteFacadeRemote)
c.lookup("java:comp/env/ejb/CompteFacade");


Il faudra remplacer le paramétre du lookup par
"BanquePlusPlus/TransactionFacade/remote"


Global JNDI Namespace
+- BanquePlusPlus (class: org.jnp.interfaces.NamingContext)
| +- CompteFacade (class: org.jnp.interfaces.NamingContext)
| | +- remote (proxy: $Proxy224 implements interface
com.insat.ejb.CompteFacadeRemote,interface org.jboss.ejb3.JBossProxy,interface
javax.ejb.EJBObject)
| +- TransactionFacade (class: org.jnp.interfaces.NamingContext)
| | +- remote (proxy: $Proxy227 implements interface
com.insat.ejb.TransactionFacadeRemote,interface org.jboss.ejb3.JBossProxy,interface
javax.ejb.EJBObject)
| +- ClientFacade (class: org.jnp.interfaces.NamingContext)
| | +- remote (proxy: $Proxy221 implements interface
com.insat.ejb.ClientFacadeRemote,interface org.jboss.ejb3.JBossProxy,interface
javax.ejb.EJBObject)

Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 19/20
Résultat de l’execution :


Voici le formulaire d’ajout de client


La page des transactions pour debiter et crediter les comptes

Atelier 4-C : Développement EJB 3.0 avec NetBeans 5.5 et JBOSS Page : 20/20

Voici la page d’affichage du compte client ainsi que son propriétaire cette page et le résultat d’une
requête d’un petit formulaire de recherche où l’utilisateur choisi le numéro de compte qu’il souhaite
afficher.

A travers cette page on aura la possibilité de modifier les paramètres du client via le lien de ce nom
qui nous amène à un formulaire de modification.



Voici le formulaire de modification avec les informations modifiable dans des textfield.