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 :

EJB3 Problème de persistence


Sujet :

JPA Java

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 60
    Par défaut EJB3 Problème de persistence
    Bonjour,

    Ma configuration :
    EJB 3.0, JBOSS, Hibernate

    j'ai besoin d'un peu d'aide sur un problème de persistence, alors voilà

    j'ai 2 entity bean, un trainer et un assistant

    Voici le trainer :

    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
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    package org.lesson.model;
     
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Collection;
    import javax.persistence.Entity;
    import javax.persistence.JoinColumn;
    import javax.persistence.OneToMany;
    import javax.persistence.OneToOne;
     
    /**
     *
     *
     */
    @Entity
    public class Trainer extends Checker implements Serializable {
     
        private Assistant assistant;
     
        @Override
        public String toString() {
            return "org.lesson.model.Trainer[id=" + userId + "]";
        }
     
        @OneToOne
        @JoinColumn(name="assistantId",referencedColumnName = "userId")
        public Assistant getAssistant() {
            return assistant;
        }
     
        public void setAssistant(Assistant assistant) {
            this.assistant = assistant;
        }
     
    }
    et voici l'assistant

    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
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    package org.lesson.model;
     
    import java.io.Serializable;
    import javax.persistence.Entity;
    import javax.persistence.JoinColumn;
    import javax.persistence.OneToOne;
     
     
    /**
     *
     
     */
    @Entity
    public class Assistant extends Checker implements Serializable {
     
        private Trainer trainer;
     
     
        @OneToOne(mappedBy="assistant")
        public Trainer getTrainer() {
            return trainer;
        }
     
        public void setTrainer(Trainer trainer) {
            this.trainer = trainer;
        }
     
     
        @Override
        public String toString() {
            return "org.lesson.model.Assistant[id=" + userId + "]";
        }
     
    }
    Pour travailler sur ces entity beans j'ai définit les session beans respectifs :

    TrainerDao :

    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
     
     
    package org.lesson.integration.dao;
     
    import java.util.List;
    import javax.ejb.Stateless;
    import javax.ejb.TransactionManagement;
    import javax.ejb.TransactionManagementType;
    import javax.ejb.TransactionAttribute;
    import javax.ejb.TransactionAttributeType;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.Query;
    import org.lesson.model.Assistant;
    import org.lesson.model.Course;
    import org.lesson.model.Trainer;
     
    @Stateless
    public class TrainerDao implements TrainerDaoLocal {
     
        @PersistenceContext (unitName = "Lesson-ejbPU")
        EntityManager em;
     
     
        public void createOrUpdate(Trainer t) {
            em.merge(t);
        }
     
     
        public void remove(Trainer t) {
            em.remove(t);
        }
     
        public void addAssistant(Trainer t,Assistant a) {
            t.setAssistant(a);
        }
     
       public Trainer find(long id){
           return em.find(Trainer.class,id);
        }
     
     
        public List<Trainer> findAll() {
            Query q = em.createQuery("SELECT t FROM Trainer t");
            return q.getResultList();  
     
        }
     
     
        public Assistant findAssistant(Trainer t) {
            return t.getAssistant();
        }
     
        // Add business logic below. (Right-click in editor and choose
        // "Insert Code > Add Business Method")
     
    }
    et AssistantDao :

    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
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    package org.lesson.integration.dao;
     
    import java.util.List;
    import javax.ejb.Stateless;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.Query;
    import org.lesson.model.Assistant;
    import org.lesson.model.Trainer;
     
    /**
     *
     
     */
     
     
    @Stateless
    public class AssistantDao implements AssistantDaoLocal {
     
       @PersistenceContext (unitName = "Lesson-ejbPU")
       EntityManager em;
     
     
        public void createOrUpdate(Assistant a){
             em.merge(a);
        }
     
     
        public void remove(Assistant a){
            em.merge(a);
        }  
     
        public  Assistant find(long id){
            return em.find(Assistant.class,id);
     
        }
     
        public List<Assistant> findAll() {
            Query q = em.createQuery("SELECT a FROM Assistant a");
            return q.getResultList();
        }  
     
        public Trainer findTrainer(Assistant a) {
           return a.getTrainer();
        }
     
     
     
        // Add business logic below. (Right-click in editor and choose
        // "Insert Code > Add Business Method")
     
    }
    Les 2 précédents sessions beans étant locaux , j'ai implémenté le pattern Façade pour les accèder en remote et les tester

    TrainerDaoFacade :

    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
     
    package org.lesson.facade;
     
    import java.util.List;
    import javax.ejb.EJB;
    import javax.ejb.Stateless;
    import org.lesson.integration.dao.TrainerDaoLocal;
    import org.lesson.model.Assistant;
    import org.lesson.model.Course;
    import org.lesson.model.Trainer;
     
    /**
     *
     
     */
    @Stateless
    public class TrainerDaoFacade implements TrainerDaoFacadeRemote {
     
        @EJB
        private TrainerDaoLocal trainerDaoLocal;
     
        public void createOrUpdate(Trainer t) {
            trainerDaoLocal.createOrUpdate(t);
        }
     
        public void remove(Trainer t) {
            trainerDaoLocal.remove(t);
        }
     
        public Trainer find(long id){
            return trainerDaoLocal.find(id);
        }
     
        public List<Trainer> findAll() {
            return trainerDaoLocal.findAll();
        }
     
     
        public void addAssistant(Trainer t, Assistant a) {
            trainerDaoLocal.addAssistant(t, a);
        }
     
        public Assistant findAssistant(Trainer t) {
            return trainerDaoLocal.findAssistant(t);
        }
     
     
     
    }
    AssistantDaoFacade :

    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
     
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    package org.lesson.facade;
     
    import java.util.List;
    import javax.ejb.EJB;
    import javax.ejb.Stateless;
    import org.lesson.integration.dao.AssistantDaoLocal;
    import org.lesson.model.Assistant;
     
    /**
     *
     
     */
    @Stateless
    public class AssistantDaoFacade implements AssistantDaoFacadeRemote {
     
        // Add business logic below. (Right-click in editor and choose
        // "Insert Code > Add Business Method")
     
        @EJB
        private AssistantDaoLocal assistantDaoLocal;
     
        public void createOrUpdate(Assistant a) {
           assistantDaoLocal.createOrUpdate(a);
        }
     
        public void remove(Assistant a) {
            assistantDaoLocal.remove(a);
        }
     
        public Assistant find(long id) {
            return assistantDaoLocal.find(id);
        }
     
        public List<Assistant> findAll() {
            return assistantDaoLocal.findAll();
        }
     
     
     
    }
    et on arrive au fichier de test JUNIT :

    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
     
         @Test
            public void addAssistant()
            {
                try {
                InitialContext ctx;
                ctx = new InitialContext(ht);
                Object ref = ctx.lookup("java:/AssistantDaoFacade/remote");
                AssistantDaoFacadeRemote assistantRemote = (AssistantDaoFacadeRemote) PortableRemoteObject.narrow(ref,AssistantDaoFacadeRemote.class);
                ref =  ctx.lookup("java:/TrainerDaoFacade/remote");
                TrainerDaoFacadeRemote trainerRemote = (TrainerDaoFacadeRemote) PortableRemoteObject.narrow(ref,TrainerDaoFacadeRemote.class);
     
                Assistant a = new Assistant();
                a.setName("assistant");
                a.setSurname("assistant");
                a.setPassword("password");
                assistantRemote.createOrUpdate(a);
     
                Trainer t = new Trainer();
                t.setName("trainer");
                t.setSurname("trainer");
                t.setPassword("password");
                trainerRemote.createOrUpdate(t);
     
                System.out.println("trainer id is : "+t.getUserId());
     
                trainerRemote.addAssistant(t, a);
                a.setTrainer(t);
     
                trainerRemote.createOrUpdate(t);
     
     
                Assistant aFound = trainerRemote.findAssistant(t);
                if(aFound == null){
                       fail("Assistant not found");
                }
     
             //   trainerRemote.createOrUpdate(t);
     
            } catch (NamingException ex) {
                Logger.getLogger(TrainerDaoFacadeTest.class.getName()).log(Level.SEVERE, null, ex);
            }
            }
    Quand j'exécute le code du test, en base l'assistant est ajouté, le trainer également. Cependant le trainer n'a pas la foreign vers l'assistant (NULL), et encore pire, lorsque je fais un createOrUpdate du même trainer le second coup un nouveau trainer est créé au lieu de faire une fusion ! et l'id que j'affiche est toujours NULL également.

    autre précision trainer et assistant héritent tous deux de la classe checker qui hérite elle même de la classe user (je ne sais pas si ça peut aider)

    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
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    package org.lesson.model;
     
    import java.io.Serializable;
    import java.util.Date;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Inheritance;
    import javax.persistence.InheritanceType;
    import javax.persistence.Temporal;
     
    /**
     *
     
     */
    @Entity(name="LESSON_USER")
    @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
    public abstract class User implements Serializable {
        private static final long serialVersionUID = 1L;
     
     
        protected Long userId;
        protected String password;
        protected String name;
        protected String surname;
        @Temporal(javax.persistence.TemporalType.DATE)
        protected Date birthdate;
     
        @Id
        @GeneratedValue(strategy = GenerationType.TABLE)
        public Long getUserId() {
            return userId;
        }
     
        public void setUserId(Long userId) {
            this.userId = userId;
        }
     
     
        public Date getBirthdate() {
            return birthdate;
        }
     
     
     
        public void setBirthdate(Date birthdate) {
            this.birthdate = birthdate;
        }
     
        public String getName() {
            return name;
        }
     
        public void setName(String name) {
            this.name = name;
        }
     
        public String getPassword() {
            return password;
        }
     
        public void setPassword(String password) {
            this.password = password;
        }
     
        public String getSurname() {
            return surname;
        }
     
        public void setSurname(String surname) {
            this.surname = surname;
        }
     
        @Override
        public int hashCode() {
            int hash = 0;
            hash += (userId != null ? userId.hashCode() : 0);
            return hash;
        }
     
        @Override
        public boolean equals(Object object) {
            // TODO: Warning - this method won't work in the case the id fields are not set
            if (!(object instanceof User)) {
                return false;
            }
            User other = (User) object;
            if ((this.userId == null && other.userId != null) || (this.userId != null && !this.userId.equals(other.userId))) {
                return false;
            }
            return true;
        }
     
        @Override
        public String toString() {
            return "org.lesson.model.User[id=" + userId + "]";
        }
     
    }
    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
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    package org.lesson.model;
     
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Collection;
    import javax.persistence.Entity;
    import javax.persistence.OneToMany;
     
    /**
     *
     
     */
    @Entity
    public abstract class Checker extends User implements Serializable {
     
     
     
    }

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 20
    Par défaut
    Bonjour,
    Commençons par le début : le getUserId() == null
    Si on fait un pas-à-pas on va avoir
    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
     
    //==== Client Side =====
    Assistant a = new Assistant(); // Reference de pointeur (id=1) côté client
    a.setName("assistant");
    a.setSurname("assistant");
    a.setPassword("password");
    assistantRemote.createOrUpdate(a); // instance Serializée d'Assistant envoyée
     
    //==== Remote Side ========
    public void createOrUpdate(Assistant a) { // Reference de pointeur (id=257818) côté remote 
       em.merge(a); // persistence en base de la reférence (id=257818) et pas (id=1)
    }
     
    // ==== Retour Client Side ======
    // a reste identique et a.getUserId() == null
     
    // Même cause même conséquence pour Trainer
    Solution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    // === Test ===
    a = assistantRemote.createOrUpdate(a);
     
    // === AssistantDao ===
    public Assistant createOrUpdate(Assistant a) { 
       em.merge(a);
       return a;
    }

    Pour l'association c'est encore plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    // TrainerDao
    public Trainer addAssistant(Trainer t,Assistant a) {
       t.setAssistant(a); // l'objet est managé certes mais pas persisté.
       em.merge(t); // <--- mieux
       return t; // <--- pour le client Side
    }

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 60
    Par défaut
    merci beaucoup michok34,

    j'ai pu résoudre mon problème grâce à ton explication. Je résonnais encore en Java de base, où tout est passé par référence, mais étant donné que le client et le serveur sont supposés ne pas être sur le même système, je suppose bien que les objets sont passés par valeurs entre client side et server side et non par référence (enfin c'est comme cela que je le comprends...)

    Par contre je fais directement un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     
    public Assistant createOrUpdate(Assistant a) { 
      return em.merge(a);
     
    }
    plutôt qu'un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public Assistant createOrUpdate(Assistant a) { 
       em.merge(a);
       return a;
    }
    sinon cela crée des doublons en base,

    en tout cas merci beaucoup

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de persistance de ma connection en ADO ?
    Par hesky dans le forum VBA Access
    Réponses: 2
    Dernier message: 08/03/2007, 14h32
  2. Réponses: 7
    Dernier message: 21/01/2007, 12h12
  3. [EJB3] problème de fetch=lazy avec ejb3
    Par pbdlpc dans le forum JPA
    Réponses: 2
    Dernier message: 16/01/2007, 21h52
  4. [Problème de persistance d'un BufferedReader]
    Par xarius dans le forum Langage
    Réponses: 2
    Dernier message: 31/05/2006, 21h44
  5. Problème LDAP (persistant!!!!!)
    Par onouiri dans le forum Développement
    Réponses: 15
    Dernier message: 27/11/2005, 11h00

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