IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java EE Discussion :

Mise en place d'EJB et tests pour une application web


Sujet :

Java EE

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 92
    Points : 48
    Points
    48
    Par défaut Mise en place d'EJB et tests pour une application web
    Bonjour, je me lance dans une appli web bien construite en utilisant au maximum jee6, et en évitant les outils comme spring hibernate ou autre. J'utilise des classes génériques pour mes entités et les accès aux bases de données avec ejb. La base de données étant derrière glassfish avec un appel jndi.

    Pour l'instant je n'ai pas réussi à faire fonctionner un test et voir si ca fonctionne. Je voudrais vous demander si les classes ont l'air correctes et quel est le moyen le plus simple pour vérifier si tout fonctionne. (cactus ? junit ?)

    Chaque entité doit pouvoir renvoyer la clé primaire typée d'où le getPK(), mais je ne sais pas si c'est une bonne idée...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import javax.persistence.Column;
    import javax.persistence.MappedSuperclass;
    import javax.persistence.Version;
     
    @MappedSuperclass
    public abstract class GenericEntity<PK> {
     
        public abstract PK getPK();
        @Column(nullable = false)
        @Version
        private Integer version;
     
        public Integer getVersion() {
            return version;
        }
     
        public void setVersion(Integer version) {
            this.version = version;
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    @Entity
    public class Utilisateur extends GenericEntity<Long> implements Serializable {
     
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        private String login;
        private String password;
     
        public Utilisateur() {
        }
     
        public Utilisateur(String login, String password) {
            this.login = login;
            this.password = password;
        }
     
        {getter/setter equals hashcode tostring}
     
        @Override
        public Long getPK() {
            return id;
        }
    }
    L'injection de l'emf se fait-elle dans la classe générique ou faut-il le placer dans chaque implémentation ? idem pour les annotations de transaction
    Faut-il placer @Stateless dans la classe générique ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    @TransactionManagement(TransactionManagementType.CONTAINER)
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public abstract class GenericManager<T extends GenericEntity, PK extends Serializable> implements iGenericManager<T, PK> {
     
        /**
         * injected JPA entity manager
         */
        @PersistenceUnit(unitName = "espheria_PU")
        private EntityManagerFactory emf;
       // @Resource
      //  private SessionContext sc;
     
        public GenericManager() {
        }
     
        public EntityManager getEntityManager() {
            return emf.createEntityManager();
        }
     
        /**    
         * returns class of T
         * @return
         */
        // @SuppressWarnings("unchecked")
        private Class<T> getEntityClass() {
            ParameterizedType ptype = (ParameterizedType) getClass().getGenericSuperclass();
            return (Class<T>) ptype.getActualTypeArguments()[0];
        }
     
        /**
         * creates entity
         *
         * @param obj
         * @return
         * @throws CreateException
         */
        public void create(T obj) throws RollbackFailureException, Exception {
            EntityManager em = null;
            try {
                em = getEntityManager();
                em.persist(obj);
            } catch (Exception ex) {
    //            try {
    //                sc.setRollbackOnly();
    //            } catch (Exception re) {
    //                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
    //            }
                throw ex;
            } finally {
                if (em != null) {
                    em.close();
                }
            }
        }
    // Autres opérations de CRUD et autres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    @Stateless
    public class UtilisateurManager extends GenericManager<Utilisateur, Long> implements iUtilisateurManager{
     
        public UtilisateurManager() {
            super();
        }
     
    }
    Les interfaces pour le moment vides :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public interface iGenericManager<T extends GenericEntity, PK extends Serializable> {
     
    }
     
    public interface iUtilisateurManager extends iGenericManager<Utilisateur,Long> {
     
    }
    Et donc si vous me lisez toujours, je cherche à tester mes managers, j'ai vu qu'avec glassfish3.1 on pouvait l'embarquer pour les tests, mais j'ai une erreur de cast :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    package fr.espheria.ejb;
     
    import fr.espheria.domain.Utilisateur;
    import java.io.File;
    import java.util.HashMap;
    import java.util.Map;
    import javax.ejb.embeddable.EJBContainer;
    import javax.naming.Context;
    import org.junit.AfterClass;
    import org.junit.BeforeClass;
    import org.junit.Test;
    import static org.junit.Assert.*;
     
    /**
     *
     * @author Gab'z
     */
    public class UtilisateurManagerTest {
     
        private static EJBContainer ec;
        private static Context ctx;
     
        @BeforeClass
        public static void initContainer() throws Exception {
            Map<String, Object> props = new HashMap<String, Object>();
            props.put(EJBContainer.MODULES, new File[]{new File("target/classes")});
            props.put(EJBContainer.APP_NAME, "test");
            props.put(EJBContainer.PROVIDER, "org.glassfish.ejb.embedded.EJBContainerProviderImpl");
     
            ec = EJBContainer.createEJBContainer(props);
            ctx = ec.getContext();
        }
     
        @AfterClass
        public static void closeContainer() throws Exception {
            if (ec != null) {
                ec.close();
            }
            if (ctx != null) {
                ctx.close();
            }
        }
     
        @Test
        public void createFormation() throws Exception {
            Utilisateur user = new Utilisateur();
            user.setLogin("Arnaud");
            user.setPassword("mdp");
            System.out.println("ERREUR JUSTE APRES CETTE LIGNE");
            UtilisateurManager um = (UtilisateurManager) ctx.lookup("java:global/test/classes/UtilisateurManager");
            um.create(user);
            assertNotNull(user.getId());
     
        }
    Et ici l'erreur du test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    34
    35
    36
    37
    38
    -------------------------------------------------------------------------------
    Test set: fr.espheria.ejb.UtilisateurManagerTest
    -------------------------------------------------------------------------------
    Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 5.186 sec <<< FAILURE!
    createFormation(fr.espheria.ejb.UtilisateurManagerTest)  Time elapsed: 0.015 sec  <<< ERROR!
    java.lang.ClassCastException: $Proxy104 cannot be cast to fr.espheria.ejb.UtilisateurManager
    	at fr.espheria.ejb.UtilisateurManagerTest.createFormation(UtilisateurManagerTest.java:54)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    	at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    	at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
    	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115)
    	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
    	at $Proxy0.invoke(Unknown Source)
    	at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
    	at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
    	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)

  2. #2
    Membre expérimenté Avatar de nathieb
    Homme Profil pro
    DevOps
    Inscrit en
    Mai 2004
    Messages
    1 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : DevOps
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 058
    Points : 1 532
    Points
    1 532
    Par défaut Complexité
    Bonjour,

    Houla, cela est bien compliqué, mais je crois que cela est dû a une certaine
    incompréhension.

    Tu as ton objet qui mappe ta table grâce à un ORM, tu utilises donc JPA 2.0
    La gestion de la clef primaire, se fait grâce à la déclaration de la variable id
    donc pas la peine de te prendre la tête.

    setId et donc getId, tu peux même utiliser la notion de séquence, avec
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)

    Ensuite tu dois créer un fichier persitence.xml

    Souvent je le fais grâce à netbeans, car je crée un connexion à la base, puis j'utilise l'éditeur create entity from database ...

    Pour ce qui est des tests tu pourras faire comme tu l'as fais ensuite.
    En règle, général j'utilise une couche intermédiaire pour les tests EJB

    Olivier
    Architecte destructurant,
    be cool, be free

    Il nous reste Debian bien sûr

Discussions similaires

  1. Comment faire des etats pour une application web ?
    Par ovh dans le forum Autres outils décisionnels
    Réponses: 6
    Dernier message: 06/07/2021, 03h25
  2. Mise en place d'un réseau Wifi pour une école
    Par vonbier dans le forum Achat et Conseils
    Réponses: 10
    Dernier message: 22/03/2013, 17h56
  3. [Méthodes]Utiliser UML ou MERISE pour une application Web ?
    Par naimoooovich dans le forum Méthodes
    Réponses: 5
    Dernier message: 28/05/2007, 11h53
  4. Quel outil de test pour une appli web ?
    Par Arnard dans le forum Tests et Performance
    Réponses: 7
    Dernier message: 31/10/2006, 09h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo