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

JPA Java Discussion :

EJB / JPA NullPointerException


Sujet :

JPA Java

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 52
    Points : 34
    Points
    34
    Par défaut EJB / JPA NullPointerException
    Bonjour,

    J'ai les classes suivantes :

    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
     
    public class BDManager {
     
        @PersistenceContext(unitName="EJBTP-ejbPU")
        private static EntityManager em;
     
        public static void add(Object o)
        {
            em.persist(o);
        }
     
        public static Object get(Class entityClass, Object pkey)
        {
            return em.find(entityClass, pkey);
        }
     
    }
    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
     
    @Entity
    @Table(name="utilisateur")
    public class UtilisateurBD implements Serializable {
        @Column(name = "login") 
        @Id
        private String login;
     
        @Column(name = "mdp")
        private String mdp;
     
        public UtilisateurBD() {
        }
     
        public UtilisateurBD(String login) {
            this.login = login;
        }
     
        public UtilisateurBD(String login, String mdp) {
            this.login = login;
            this.mdp = mdp;
        }
     
        public String getLogin()
        {
            return login;
        }
     
        public String getMdp()
        {
            return mdp;
        }
     
        public void setLogin(String login) {
            this.login = login;
        }
     
        public void setMdp(String mdp) {
            this.mdp = mdp;
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    @Remote
    public interface Utilisateur {
     
        public void ajouter(String login, String mdp);
     
        public void get(String login);
     
        public String getLogin();
     
        public String getMdp();
     
     
    }
    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
     
    @Stateless
    public class UtilisateurBean implements Utilisateur {
     
        private UtilisateurBD util;
     
        public UtilisateurBean() {
        }
     
        @Override
        public void ajouter(String login, String mdp)
        {
            BDManager.add(new UtilisateurBD(login, mdp));
        }
     
        @Override
        public void get(String login)
        {
            util = (UtilisateurBD) BDManager.get(UtilisateurBD.class, login);
        }
     
        @Override
        public String getLogin()
        {
            return util.getLogin();
        }
     
        @Override
        public String getMdp()
        {
            return util.getMdp();
        }
     
    }
    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
     
    @WebServlet(name="EntityServlet", urlPatterns={"/EntityServlet"})
    public class EntityServlet extends HttpServlet {
     
        @EJB
        Utilisateur util = null;
     
        protected void processRequest(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    [...]
     
    String login = request.getParameter("login");
            String mdp = request.getParameter("mdp");
     
            util.ajouter(login, mdp);
    }
    }
    A l'exécution, j'obtiens l'erreur suivante lors d'un ajout ou get d'utilisateur :

    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
     
    ATTENTION: A system exception occurred during an invocation on EJB UtilisateurBean method public void tp2pdf.entity.ejb.UtilisateurBean.ajouter(java.lang.String,java.lang.String)
    javax.ejb.EJBException
            at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5119)
            at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5017)
            at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4805)
            at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2004)
            at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1955)
            at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:208)
            at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:75)
            at $Proxy207.ajouter(Unknown Source)
            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 com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:228)
            at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:147)
            at com.sun.corba.ee.impl.presentation.rmi.codegen.CodegenStubBase.invoke(CodegenStubBase.java:225)
            at tp2pdf.entity.ejb.__Utilisateur_Remote_DynamicStub.ajouter(tp2pdf/entity/ejb/__Utilisateur_Remote_DynamicStub.java)
            at tp2pdf.entity.ejb._Utilisateur_Wrapper.ajouter(tp2pdf/entity/ejb/_Utilisateur_Wrapper.java)
            at tp2pdf.entity.EntityServlet.addUtil(EntityServlet.java:141)
            at tp2pdf.entity.EntityServlet.processRequest(EntityServlet.java:59)
            at tp2pdf.entity.EntityServlet.doPost(EntityServlet.java:115)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
            at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
            at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
            at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
            at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
            at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
            at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:239)
            at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
            at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
            at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
            at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
            at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
            at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
            at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
            at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
            at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
            at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
            at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
            at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
            at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
            at java.lang.Thread.run(Thread.java:619)
    Caused by: java.lang.NullPointerException
            at tp2pdf.entity.bd.BDManager.add(BDManager.java:23)
            at tp2pdf.entity.ejb.UtilisateurBean.ajouter(UtilisateurBean.java:30)
            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.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1056)
            at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1128)
            at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5292)
            at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:615)
            at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:797)
            at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:567)
            at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:157)
            at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:139)
            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 com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:858)
            at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:797)
            at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:367)
            at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5264)
            at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5252)
            at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:201)
            ... 40 more
     
    ATTENTION: StandardWrapperValve[EntityServlet]: PWC1406: Servlet.service() for servlet EntityServlet threw exception
    javax.ejb.EJBException
            at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5119)
            at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5017)
            at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4805)
            at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2004)
            at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1955)
            at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:208)
            at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:75)
            at $Proxy207.ajouter(Unknown Source)
            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 com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:228)
            at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:147)
            at com.sun.corba.ee.impl.presentation.rmi.codegen.CodegenStubBase.invoke(CodegenStubBase.java:225)
            at tp2pdf.entity.ejb.__Utilisateur_Remote_DynamicStub.ajouter(tp2pdf/entity/ejb/__Utilisateur_Remote_DynamicStub.java)
            at tp2pdf.entity.ejb._Utilisateur_Wrapper.ajouter(tp2pdf/entity/ejb/_Utilisateur_Wrapper.java)
            at tp2pdf.entity.EntityServlet.addUtil(EntityServlet.java:141)
            at tp2pdf.entity.EntityServlet.processRequest(EntityServlet.java:59)
            at tp2pdf.entity.EntityServlet.doPost(EntityServlet.java:115)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
            at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
            at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
            at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
            at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
            at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
            at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:239)
            at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
            at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
            at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
            at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
            at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
            at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
            at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
            at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
            at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
            at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
            at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
            at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
            at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
            at java.lang.Thread.run(Thread.java:619)
    Caused by: java.lang.NullPointerException
            at tp2pdf.entity.bd.BDManager.add(BDManager.java:23)
            at tp2pdf.entity.ejb.UtilisateurBean.ajouter(UtilisateurBean.java:30)
            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.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1056)
            at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1128)
            at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5292)
            at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:615)
            at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:797)
            at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:567)
            at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:157)
            at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:139)
            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 com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:858)
            at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:797)
            at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:367)
            at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5264)
            at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5252)
            at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:201)
            ... 40 more
    Avez-vous une idée de la cause du problème ?

    A noter que dans une différente manière d'écrire ces classes, tout marchait bien, donc je ne pense pas que ça soit un problème de Glassfish ou du SGBD.

    Merci d'avance.

  2. #2
    Membre éprouvé
    Avatar de hasalex
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2009
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2009
    Messages : 879
    Points : 1 269
    Points
    1 269
    Par défaut
    Il y aurait pas mal de choses à dire sur ton code. Pour rester cordial, je dirais qu'il n'est pas très agréable à lire.

    Pour se centrer sur ton problème, il vient probablement du fait que tu utilises des méthodes statiques dans BDManager. Fais des méthodes normales, et injecte une instance de BDManager dans ton EJB. Ainsi, tu permettras à ton app server d'injecter le PersistenceContext.

  3. #3
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Même avis qu'hasalex
    Je ne vois pas l'intérêt de ta classe DBManager.
    Si tu mets ton programme en debug, je pense que tu verras que l'entityManager n'a pas été injecté.
    Pourquoi ne pas mettre cet élément dans ton ejb stateless ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 52
    Points : 34
    Points
    34
    Par défaut
    L'intérêt de la classe BDManager est d'être utilisée par tout EJB de mon projet. Si je met directement l'entityManager dans Utilisateur, il va falloir que j'en déclare un nouveau pour chaque autre EJB.

    De même pour le choix du static, si je retire la mention, cela signifie que je vais avoir une nouvelle instance de BDManager pour chaque EJB, or je n'en ai besoin que d'un seul, soit un seul entityManager pour tout le projet.

    Comment je fais pour 'injecter une instance de BDManager dans mon EJB' ? J'ai essayé différentes variantes mais elles ont toutes échoué.

    Je cherche la meilleure manière de réaliser tout ça, j'aimerais donc savoir aussi ce qu'il faut améliorer dans le code au niveau architecture pour que ça soit mieux, je débute dans les EJB donc tout conseil est bon à prendre.

  5. #5
    Membre régulier
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2006
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 49
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 114
    Points : 101
    Points
    101
    Par défaut
    Bonjour, d'après ce que tu dis tu voudrais une unique instance de BDManager càd un singleton. Je pense que c'est un très mauvais choix mais si tu restes sur cette idée, il faut regarder du côté de JEE 6 (@Singleton).

  6. #6
    Membre éprouvé
    Avatar de hasalex
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2009
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2009
    Messages : 879
    Points : 1 269
    Points
    1 269
    Par défaut
    Je pense que tu devrais commencer par lire un bon bouquin sur JavaEE, histoire d'avoir les idées plus claires.

    En terme d'architecture, ton BDManager est ce qu'on appelle communément un DAO, qui peut éventuellement être un singleton.

    Concernant ton EntityManager, il faut en avoir plusieurs instances. Laisse ton app serveur gérer cet aspect. C'et l'EntityManagerFactory qui sera un singleton, mais là aussi, laisse gérer ton app server gérer ça.

    Pour injecter un DAO dans un EJB, tu as 2 possibilités. Ton DAO peut être un EJB lui aussi. Et si tu utilises Java EE 6, tu peux faire une injection par CDI avec @Inject.

  7. #7
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Tu peux aussi factoriser le code standard d'un DAO, comme dans cet exemple
    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
     
    public interface GenericDAO<T, I extends Serializable>
    {
        public EntityManager getEntityManager();
     
        public T find(I id);
     
        public List<T> findAll();
     
        public T save(T t);
     
        public T update(T t);
     
        public void delete(I id);
     
        public void delete(T t);
    }
    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
     
    public abstract class GenericDAOImpl<T, I extends Serializable> implements GenericDAO<T, I>
    {
        protected Class<? extends T> clazz;
        protected static Logger logger;
     
        /**
         * Constructeur générique
         */
        @SuppressWarnings("unchecked")
        protected GenericDAOImpl()
        {
            this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
            logger = Logger.getLogger(clazz);
        }
     
        /**
         * Récupération de l'objet pour la clé recherchée
         */
        public T find(I id)
        {
            logger.debug("get(id) " + id);
            try
            {
                return (T) getEntityManager().find(clazz, id);
            }
            catch (Exception e)
            {
                return null;
            }
        }
     
        /**
         * Suppression de l'objet pour la clé recherchée
         */
        public void delete(I id)
        {
            logger.debug("delete(id) " + id);
            delete(find(id));
        }
     
        /**
         * Suppression de l'objet
         */
        public void delete(T t)
        {
            logger.debug("delete(T) : " + t.toString());
            t = (T)getEntityManager().merge(t);
            getEntityManager().remove(t);
        }
     
        /**
         * Ajouter
         */
        public T save(T t)
        {
            logger.debug("save(T) : " + t.toString());
            getEntityManager().persist(t);
            getEntityManager().flush();
            return (T) t; 
        }
     
        /**
         * Modifier un objet
         */
        public T update(T t)
        {
            logger.debug("update(T) : " + t.toString());
            T entity = (T) getEntityManager().merge(t);
            return (T) entity;
        }
     
     
        /**
         * Récupération de tous les enregistrements
         */
        @SuppressWarnings("unchecked")
        public List<T> findAll()
        {
            logger.debug("findAll()");
            return getEntityManager().createQuery("select a from " + clazz.getName() + " a").getResultList();
        }
     
    }
    Ensuite, tu utilises comme tu veux
    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
     
     
    @Local
    public interface UnEJBLocal extends GenericDAO<TypeEntity, Integer>
    {
        ... Signature des méthodes non traitées par GenericDAO
    }
     
     
    @Stateless
    public class UnEJBImpl extends GenericDAOImpl<TypeEntity, Integer> implements UnEJBLocal
    {
        @PersistenceContext(unitName="MaPU")
        protected EntityManager entityManager;
     
        /**
         * Entity Manager
         */
        public EntityManager getEntityManager()
        {
            return entityManager;
        }
     
        ... code non traité par GenericDAOImpl
     
    }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 52
    Points : 34
    Points
    34
    Par défaut
    Concernant ton EntityManager, il faut en avoir plusieurs instances. Laisse ton app serveur gérer cet aspect. C'et l'EntityManagerFactory qui sera un singleton, mais là aussi, laisse gérer ton app server gérer ça.

    Pour injecter un DAO dans un EJB, tu as 2 possibilités. Ton DAO peut être un EJB lui aussi. Et si tu utilises Java EE 6, tu peux faire une injection par CDI avec @Inject.
    En fait c'est plutôt niveau code que j'ai un problème. Mon code actuel bloque en effet sur l'entityManager qui est à null quand on lui demande un service, d'où le NullPointerException.

    J'avais essayé avec entityManagerFactory mais ça échouait systématiquement, et concernant le context lookup, peu importe ce que je met "java:module/BDManager" ou "java:comp/BDManager" ou "java:comp/env/BDManager" ça échoue, j'ai mis BDManager.getClass().getName() mais j'obtiens un autre type d'exception.

    Comment dois-je adapter précisément mes classes pour que ça fonctionne ? Pour les questions d'architecture, je verrai à un autre moment.

  9. #9
    Membre éprouvé
    Avatar de hasalex
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2009
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2009
    Messages : 879
    Points : 1 269
    Points
    1 269
    Par défaut
    Réellement, et sans vouloir dénigrer ton travail, ton problème n'est pas encore au niveau du code, bien bien de ton architecture et de la compréhension des mécanismes de JavaEE. J'insiste, lis un livre sur le sujet.

    Si tu veux faire court, essaie avec le code de OButterlin, il te permettra de démarrer sur de bonnes bases.

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 52
    Points : 34
    Points
    34
    Par défaut
    J'ai eu accès à un programme en entreprise et j'ai pu voir un peu l'architecture, j'ai donc remanié tout ça avec les classes suivantes :

    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
    56
     
    @Entity
    @Table(name="utilisateur")
    public class Utilisateur implements Serializable {
        @Column(name = "login")     
        @Id
        private String login;
     
        @Column(name = "mdp")
        private String mdp;
     
        @OneToMany(mappedBy="owner", fetch = FetchType.EAGER, cascade=CascadeType.ALL)    
        private List<Compte> comptes = new ArrayList<Compte>();
     
        public Utilisateur() {
        }
     
        public Utilisateur(String login) {
            this.login = login;
        }
     
        public Utilisateur(String login, String mdp) {
            this.login = login;
            this.mdp = mdp;
        }
     
        public String getLogin()
        {
            return login;
        }
     
        public String getMdp()
        {
            return mdp;
        }
     
        public void setLogin(String login) {
            this.login = login;
        }
     
        public void setMdp(String mdp) {
            this.mdp = mdp;
        }
     
        public List<Compte> getComptes()
        {
            return comptes;
        }
     
        public String toString()
        {
            return login;
        }
     
     
    }
    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
     
    @Entity
    @Table(name="compte")
    public class Compte implements Serializable{
     
        @Column(name = "id")
        @Id
        @GeneratedValue
        private Integer id;
     
        @Column(name = "nom")
        private String nom;
     
        @ManyToOne
        @JoinColumn (name="utilisateur") 
        private Utilisateur owner;
     
        public Compte() {
        }
     
        public Compte(Utilisateur util, String nom)
        {
            this.owner = util;
            this.nom = nom;
        }
     
        public Integer getId()
        {
            return id;
        }
     
        public String getNom()
        {
            return nom;
        }
     
        public Utilisateur getOwner()
        {
            return owner;
        }
     
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public interface UtilisateurDaoInterface {
     
        public void add(Utilisateur util);
     
        public Utilisateur get(String login);
     
        public List<Compte> getComptes(String loginUtilisateur);
     
     }
    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
     
    @Stateless
    public class UtilisateurDao implements UtilisateurDaoInterface {
     
        @PersistenceContext(unitName="EJBTP-ejbPU")
        private EntityManager em;
     
        @Override
        public void add(Utilisateur util)
        {
            em.persist(util);
        }
     
        @Override
        public Utilisateur get(String login)
        {
            return em.find(Utilisateur.class, login);
        }
     
        public List<Compte> getComptes(String loginUtilisateur)
        {
            return this.get(loginUtilisateur).getComptes();
        }
     
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public interface CompteDaoInterface {
     
        public void add(Compte compte);
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    @Stateless
    public class CompteDao implements CompteDaoInterface {
     
        @PersistenceContext(unitName="EJBTP-ejbPU")
        private EntityManager em;
     
        @Override
        public void add(Compte compte) {
            em.persist(compte);
        }
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    @Remote
    public interface Gestion {
     
        public void add(Utilisateur u);
     
        public Utilisateur get(String login);
     
        public void addCompte(Compte compte);
     
        public List<Compte> getComptes(String loginUtilisateur);
     
    }
    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
    @Stateless
    public class GestionBean implements Gestion {
     
        @EJB
        private UtilisateurDaoInterface util;
     
        @EJB
        private CompteDaoInterface compte;
     
        public void add(Utilisateur u)
        {
            util.add(u);
        }
     
        public Utilisateur get(String login)
        {
            return util.get(login);
        }
     
        public void addCompte(Compte c)
        {
            compte.add(c);
        }
     
        public List<Compte> getComptes(String loginUtilisateur) {
            return util.getComptes(loginUtilisateur);
        }
     
    }
    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
     
    @WebServlet(name="EntityServlet", urlPatterns={"/EntityServlet"})
    public class EntityServlet extends HttpServlet {
     
        @EJB
        Gestion gestion;
     
        protected void processRequest(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
     
    [...]
     
            gestion.add(new Utilisateur(login, mdp));
     
    [...]
     
            Utilisateur u = gestion.get(login);
     
    [...]
     
            gestion.addCompte(new Compte(new Utilisateur(loginUtilisateur), nom));
     
    [...]
     
            List<Compte> lc = gestion.getComptes(loginUtilisateur);
    Ceci fonctionne, à part peut être les mises à jour des comptes d'un utilisateur qui foire un peu.

    Est-ce que l'architecture se rapproche plus de quelque chose de propre ?

  11. #11
    Membre éprouvé
    Avatar de hasalex
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2009
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2009
    Messages : 879
    Points : 1 269
    Points
    1 269
    Par défaut
    L'architecture est bonne, c'est un très bon point de départ.
    Vois-tu ce qu'on te poussait à faire : tu n'as plus de méthode static, que des méthodes d'instance, et tu laisse ton app server gérer les injections.

    Il y a quand même des remarques à faire, en particulier pour ton entité Utilisateur, tu utilises login comme PK. Il vaut mieux en général utiliser des clés techniques, auto-générées et te contenter d'un @Unique sur ta propriété login.

  12. #12
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Personnellement, je la trouve bonne, et l'utilisation de login comme clé primaire ne me dérange plus que ça même si je préfère, si c'est possible, de n'utiliser que des clés incrémentales, mais bon, d'autres auront des avis différents.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 52
    Points : 34
    Points
    34
    Par défaut
    Par rapport à cette architecture, je trouve qu'elle force d'avoir beaucoup de surcouches pas forcément utiles, de même pour les interfaces. Aussi, on doit avoir un entityManager pour chaque entity. Au final il y a quand même 9 classes au lieu de 5, j'espère que ce n'est pas pour rien ^_^

    Je sais qu'en général on préfère avoir des entiers auto générés pour les clés primaires des tables, mais concernant la table utilisateur, il y a une vraie volonté d'unicité du login, je sais par expérience que pour ce type de table précis, il vaut mieux faire ainsi. Après peut-être il y a d'autres raisons de préférer des entiers, mais lors d'un projet j'ai été piégé par cela.

  14. #14
    Membre éprouvé
    Avatar de hasalex
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2009
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2009
    Messages : 879
    Points : 1 269
    Points
    1 269
    Par défaut
    9 au lieu de 5 ??? Tu en avais 5, mais sans Compte ! Tu en as 6 au lieu de 5.

    Concernant les interfaces, tu as raison, dans ton cas c'est inutile. En JavaEE 6, tu peux t'en passer. Donc vire les.
    Et si tu veux simplifier l'architecture, tu peux aussi virer les DAOs. Dans ton cas, chaque méthode de DAO fait 1 seul ligne, ça ne sert pas à grand chose. Dans ce cas, il faut injecter l'EntityManager dans chaque EJB.

    Et au fait, pourquoi Gestion est en @Remote ?

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 52
    Points : 34
    Points
    34
    Par défaut
    En fait je parlais par rapport à la dernière version qui marchait : BDManager, BDInterface, Utilisateur, Compte, Servlet = 5 classes, et maintenant UtilisateurDao, UtilisateurDaoInterface, Utilisateur, CompteDao, CompteDaoInterface, Compte, Gestion, GestionBean, Servlet = 9 classes.

    Je comprends toujours pas très bien ce principe 'd'injecter l'EntityManager', sur les tutos sur internet j'ai trouvé 3 méthodes : context lookup, entityManagerFactory, et @EJB, j'ai perdu beaucoup de temps sur des variantes qui marchaient pas.

    Gestion doit être en Remote pour indiquer qu'il faut injecter GestionBean non ? Pour l'instanciation dans la Servlet.

  16. #16
    Membre éprouvé
    Avatar de hasalex
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2009
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Janvier 2009
    Messages : 879
    Points : 1 269
    Points
    1 269
    Par défaut
    OK fait en sorte que ça marche, puis lis un livre sur JavaEE 6. Tu as vraiment beaucoup de choses à apprendre sur ces technos, trop pour que ce soit traité sur un forum.

  17. #17
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 52
    Points : 34
    Points
    34
    Par défaut
    J'ai un petit problème à cette méthode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public List<Compte> getComptes(String loginUtilisateur)
        {
            return this.get(loginUtilisateur).getComptes();
        }
    Cette méthode fonctionne au premier coup, par contre si je l'appelle une fois, et que j'appelle addCompte(compte) ensuite, lorsque je fais appel à nouveau à getComptes, le compte que j'ai ajouté entre temps n'apparait pas, je pense que c'est parce que l'instance n'a pas été rafraîchie, que dois je modifier pour gérer ce cas?

  18. #18
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    tu n'as pas persisté entre les 2 opérations, ton get recharge l'entity
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  19. #19
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 52
    Points : 34
    Points
    34
    Par défaut
    Appeler
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public void add(Compte compte) {
            em.persist(compte);
        }
    entre les 2 ne suffit pas?

  20. #20
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    d'après ton mapping, c'est utilisateur qui gère la relation, pas compte.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. [EJB3] Erreur de lancement d'application EJB, JPA, JSF
    Par steave dans le forum Java EE
    Réponses: 5
    Dernier message: 14/10/2009, 23h18
  2. Réponses: 0
    Dernier message: 25/08/2009, 17h38
  3. web - ejb - jpa - maven
    Par ekremyilmaz dans le forum Maven
    Réponses: 2
    Dernier message: 29/01/2009, 00h24
  4. JBoss + EJB + JPA
    Par ghnawfal dans le forum Wildfly/JBoss
    Réponses: 18
    Dernier message: 08/08/2008, 13h46
  5. Réponses: 4
    Dernier message: 02/08/2008, 19h56

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