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 :

Recharger un entity


Sujet :

JPA Java

  1. #1
    Membre confirmé Avatar de kimausoleil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2004
    Messages : 126
    Par défaut Recharger un entity
    Bonjour !

    J'ai 2 entités (Client et Contact), un stateless session bean, un controller jsf, et plusieurs pages jsp...

    Un client se connecte, je garde mon controller dans ma session
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    @ManagedBean
    @SessionScoped
    public class AccountController extends AbstractController
    , je modifie mes données, et visualise les contacts que je peux également modifier....


    Je voudrais pouvoir recharger (ou rafraichir mon stateless bean) lorsque je navigue dans mes pages pour voir si des modifications ont été réalisées entre temps....


    Pour l'instant, dans mon stateless je rechargeais toujours mon entity en créant une autre instance :

    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
    
       @Override
        public Client findClient(int id) {
            Client client = em.find(Client.class, id);
            return client;
        }
    
        @Override
        public List<Contact> findContacts(Client client) {
            return findClient(client.getId).getContactList();
        }
    
        @Override
        public Client refreshClient(Client client) {
            return findClient(client.getId);
        }
    Puis j'ai pensé à faire de cette manière :
    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
    
       @Override
        public Client findClient(int id) {
            Client client = em.find(Client.class, id);
            return client;
        }
    
        @Override
        public List<Contact> findContacts(Client client) {
            em.refresh(client);
            return client.getContactList();
        }
    
        @Override
        public Client refreshClient(Client client) {
            em.refresh(client);
            return client;
        }
    Mais là... une belle petite exception :
    java.lang.IllegalArgumentException: Can not refresh not managed object
    Donc, il est possible de rafraichir qu'après un "persist" ou un "merge"...

    Alors, est-ce que ma 1ère méthode est bonne ?

    Merci

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     @Override
        public List<Contact> findContacts(Client client) {
            em.refresh(client);
            return client.getContactList();
        }
    Ce client que tu veux rafraichir, comment l'as tu récupéré? tu sais bien qu'on ne peut rafraichir une entité que lorsqu'elle est attachée à un contexte de persistence j'espere? une autre question je suppose que tu veux la rafraichir parceque tu suppose que lors de la navigation un autre utilisateur l'a peut être modifié en base?

  3. #3
    Membre confirmé Avatar de kimausoleil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2004
    Messages : 126
    Par défaut
    Citation Envoyé par DevServlet Voir le message
    Ce client que tu veux rafraichir, comment l'as tu récupéré? tu sais bien qu'on ne peut rafraichir une entité que lorsqu'elle est attachée à un contexte de persistence j'espere?
    J'avais oublié
    Donc il n'y a pas un moyen de garder...


    Citation Envoyé par DevServlet Voir le message
    une autre question je suppose que tu veux la rafraichir parceque tu suppose que lors de la navigation un autre utilisateur l'a peut être modifié en base?
    Oui c'est exactement ça !
    Alors je garde la 1ère méthode ou pas ?

    Merci

  4. #4
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Par défaut
    Peux tu repondre à ma question? , comment recuperes tu l'entité que tu veux rafraichir par la suite?

  5. #5
    Membre confirmé Avatar de kimausoleil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2004
    Messages : 126
    Par défaut
    Citation Envoyé par DevServlet Voir le message
    Peux tu repondre à ma question? , comment recuperes tu l'entité que tu veux rafraichir par la suite?
    Ok voilà comme je procède .

    1. J'ai ma page jsp qui appelle mon controller jsf

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
       
                      <h:commandLink action="#{accountController.displayContacts}">
                          <h:outputText value="Contacts" />
                      </h:commandLink>
      et qui m'affiche la page jsp et donc les contacts :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
       
                          <h:form>
       
                              <h:dataTable value="#{accountController.contacts}" var="contact" columnClasses="contactCol1, contactCol2, contactCol3">
                                  <h:column>
                                      <f:facet name="header">
                                          <h:outputText value="Contact"/>
                                      </f:facet>
                                      <h:outputText value="#{contact.pnom} #{contact.ppren}" />
                                  </h:column>
                                  (...)
                              </h:dataTable>
       
                          </h:form>
    2. controller qui est dans ma session

      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
      @ManagedBean
      @SessionScoped
      public class AccountController extends AbstractController {
      
          @EJB
          private ClientFacadeLocal clientBean;
      
          private Client client;
          private List<Contact> contacts;
      
          (...)
      
          public String displayContacts() {
              String navigateTo = "client.contacts";
              contacts = clientBean.findContacts(client);
              return navigateTo;
          }
      
          (...)
      
          public List<Contact> getContacts() {
              return contacts;
          }
      
          (...)
      
      }
    3. avec mon stateless tel que :

      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
       
      @Stateless
      public class ClientFacade extends AbstractFacade<Client> implements ClientFacadeLocal, ClientFacadeRemote {
       
          @PersistenceContext(unitName = "CCLegiePU")
          private EntityManager em;
       
          (...)
       
         @Override
          public Client findClient(int id) {
              Client client = em.find(Client.class, id);
              return client;
          }
       
          @Override
          public List<Contact> findContacts(Client client) {
              return findClient(client.getId).getContactList();
          }
       
          (...)
       
      }


    Voilà !

    Donc en fait, est-ce que cette méthode est valide pour afficher ma liste de contacts à jour ?

    Merci

  6. #6
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Par défaut
    Oui ca va tu peux le laisser ainsi.

  7. #7
    Membre confirmé Avatar de kimausoleil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2004
    Messages : 126
    Par défaut Ok... sinon...
    Ok pour recharger tout l'entity Client même si je ne veux recharger que les contacts.

    Sinon, j'ai pensé plutôt recharger par JPQL ma liste de contacts sachant que :

    1. Liaison 1:n entre Client et Contact

      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
       
      @Entity
      public class Client implements Serializable {
       
          @Id
          @GeneratedValue(strategy = GenerationType.IDENTITY)
          @Column(name = "cid")
          private Integer cid;
       
          (...)
       
          @OneToMany(cascade = CascadeType.ALL, mappedBy = "client")
          private List<Contact> contactList;
       
          (...)
      }
      et

      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
      @Entity
      public class Contact implements Serializable {
      
          @Id
          @GeneratedValue(strategy = GenerationType.IDENTITY)
          @Column(name = "pid")
          private Integer pid;
      
          (...)
      
          @JoinColumn(name = "pidc", referencedColumnName = "cid")
          @ManyToOne(optional = false)
          private Client client;
      
          (...)
      }
      RMQ : pidc est donc la clé étrangère liant la table Contact avec la table Client.

    2. Fonction findContacts avec requête dans mon stateless

      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
       
      @Stateless
      public class ClientFacade extends AbstractFacade<Client> implements ClientFacadeLocal, ClientFacadeRemote {
       
          @PersistenceContext(unitName = "CCLegiePU")
          private EntityManager em;
       
          @Override
          public List<Contact> findContacts(Client client) {
       
              List<Contact> contacts;
              Query query = em.createQuery("SELECT c FROM Contact c WHERE c.pidc=:pidc");
              query.setParameter("pidc", client.getId());
              contacts = (List<Contact>) query.getResultList();
       
              return contacts;
       
      //        Client client = findClient(client.getId()));
      //        return client.getContactList();
          }
       
      }


    Et là... une EJBException :
    javax.ejb.EJBException

    root cause

    java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:
    Exception Description: Error compiling the query [SELECT c FROM Contact c WHERE c.pidc=:pidc], line 1, column 32: unknown state or association field [pidc] of class [entity.Contact]


    De ce fait, je crée alors le champ pidc clé étrangère dans mon entity Contact tel que
    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
    @Entity
    public class Contact implements Serializable {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "pid")
        private Integer pid;
    
        @Basic(optional = false)
        @Column(name = "pidc")
        private Integer pidc;
    
        (...)
    
        @JoinColumn(name = "pidc", referencedColumnName = "cid")
        @ManyToOne(optional = false)
        private Client client;
    
        (...)
    }
    et là... nouvelle exception

    GRAVE: Local Exception Stack:
    Exception [EclipseLink-0] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.IntegrityException
    Descriptor Exceptions:
    ---------------------------------------------------------
    Exception [EclipseLink-48] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.DescriptorException
    Exception Description: Multiple writable mappings exist for the field [contact.pidc]. Only one may be defined as writable, all others must be specified read-only.
    Mapping: org.eclipse.persistence.mappings.OneToOneMapping[client]
    Descriptor: RelationalDescriptor(entity.Contact --> [DatabaseTable(contact)])


    Ce que je comprends, c'est que ce champ pidc ne peut-être modifié (car c'est celui qui lie le Contact au Client), mais j'en ai besoin pour ma requête...

    Comment faire ? Ou je suis complètement à l'ouest ?

    Merci

  8. #8
    Membre confirmé Avatar de kimausoleil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2004
    Messages : 126
    Par défaut
    Bon donc finalement, j'ai chargé ma liste de contacts par NativeQuery...

    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
     
        @Override
        public List<Contact> findContacts(Client client) {
     
            List<Contact> contacts;
    //        Query query = em.createQuery("SELECT c FROM Contact c WHERE c.pidc=:pidc");
    //        query.setParameter("pidc", client.getId());
    //        contacts = (List<Contact>) query.getResultList();
            Query query = em.createNativeQuery("SELECT * FROM Contact WHERE pidc=" + client.getId(), Contact.class);
            contacts = query.getResultList();
            return contacts;
     
    //        Client client = findClient(client.getId());
    //        return client.getContactList();
        }
    Là au moins ça marche !

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

Discussions similaires

  1. [JSP][servlet]rechargement de la page
    Par deldin dans le forum Servlets/JSP
    Réponses: 4
    Dernier message: 09/06/2004, 12h14
  2. [VB.NET] Provoquer le rechargement d'un user control..
    Par didoboy dans le forum ASP.NET
    Réponses: 7
    Dernier message: 30/04/2004, 14h17
  3. ACTIVE X Controle recharger
    Par philippe V dans le forum MFC
    Réponses: 4
    Dernier message: 16/01/2004, 21h02
  4. [ Entity bean ] CMP
    Par hocinema dans le forum Websphere
    Réponses: 5
    Dernier message: 03/10/2003, 11h33
  5. [web] rechargement de page html
    Par GMI3 dans le forum Web
    Réponses: 2
    Dernier message: 22/09/2003, 09h49

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