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 stateless et JPA sont sur un bateau. . . et le client est sur la terre ferme


Sujet :

JPA Java

  1. #1
    Membre éprouvé

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    733
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 733
    Points : 1 119
    Points
    1 119
    Par défaut EJB stateless et JPA sont sur un bateau. . . et le client est sur la terre ferme
    Bonjour à tous,

    J'ai un problème de compréhension/mise en application de JPA au sein d'un EJB stateless et des chargements à la demande. Je vais exprimer mon problème avec un exemple tout simple.

    Voici les entity JPA :
    Personnes :
    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
    package cnam.entite;
     
    import static javax.persistence.CascadeType.MERGE;
    import static javax.persistence.CascadeType.PERSIST;
    import static javax.persistence.CascadeType.REMOVE;
    import static javax.persistence.CascadeType.ALL;
    import static javax.persistence.FetchType.LAZY;
     
    import java.io.Serializable;
    import java.sql.Timestamp;
    import java.util.List;
     
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.OneToMany;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;
     
    @Entity
    @Table(name="t_client", schema = "ecommerce")
    public class Client implements Serializable {
    	@Id
    	@GeneratedValue(strategy=GenerationType.AUTO)
    	private int identifiant;
     
    	private String nom;
     
     
    	private Timestamp datenaissance;
     
    	private String password;
     
    	@OneToOne(cascade=ALL, fetch = FetchType.LAZY)
    	@JoinColumn(name="fk_id_adresse")
    	private Adresse adresse;
     
    	private String prenom;
     
    	private String email;
     
    	private String login;
    	private static final long serialVersionUID = 1L;
     
    	//getter & setter
    	public String toString(){
    		StringBuffer sb=new StringBuffer("Id : "+getIdentifiant()+" Nom : ");
    		sb.append(getNom());
    		sb.append(" Prenom : ");
    		sb.append(getPrenom());
    		return sb.toString();
    	}	
    }
    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
    package cnam.entite;
     
    import java.io.Serializable;
     
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
     
    @Entity
    @Table(name="t_adresse", schema = "ecommerce")
    public class Adresse implements Serializable {
    	@Id
    	@GeneratedValue(strategy=GenerationType.AUTO)
    	private int id;
     
    	private String adr4;
     
    	private String ville;
     
    	private String adr1;
     
    	private String adr3;
     
    	private int codepostal;
     
    	private String adr2;
     
    	private static final long serialVersionUID = 1L;
     
    	public Adresse() {
    		super();
    	}
    	//getters et setters
     
    	@Override
    	public String toString() {
    		return String.format("[%d, %s,%s, %s, %s, %d, %s]", getId(),getAdr1(),getAdr2(),getAdr3(), getAdr4(),getCodepostal(),getVille());
    	}
    }
    Comme vous pouvez le voir, c'est un exemple très classique. Lors que je fais des tests locaux avec un entityManager créé en dehors d'un serveur d'application. La méthode getAdresse() s'exécute correctement et me ramène les adresses des clients lorsque j'en ai le besoin.



    Ces entités JPA sont accessibles par un EJB stateless+interface distance.
    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
    @Stateless
    public class ClientBean implements ClientLocal, ClientRemote {
    	@PersistenceContext(unitName="EcommerceEJB-JNDI")
    	private EntityManager em;
     
    	public Client createClient(Client client, Adresse adresse) {
    		client.setAdresse(adresse);
    		em.persist(client);
    		return client;
    	}
     
    	public Client createClient(Client client) {		
    		em.persist(client);
    		return client;
    	}
    	public Client rechercherClientById(int id){
    		return em.find(Client.class, id);
    	}
    	public void deleteClient(Client client) {
    		client=em.merge(client);
    		em.remove(client);
    	}
    	public Client updateClient(Client client) {
    		client=em.merge(client);
    		return client;
    	}
    	@SuppressWarnings("unchecked")
    	public List<Client> getClients(){
    		Query clients=em.createQuery("Select c from Client c");
    		List<Client> res=(List<Client>)clients.getResultList();
    		return res;
    	}
    }
    Là aussi rien de bien compliqué non plus.

    Et là j'ai mon problème avec mon programme client de cet EJB et le chargement des adresses.
    Si mon client effectue cette boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (Client client : clientBean.getClients()) {
    			System.out.println("Clien :"+client.getIdentifiant());
    			System.out.println("Clien :"+client.getAdresse());
    		}
    Je vais avoir une exception sur le LazyLoading :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
    	at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
    	at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:166)
    	at cnam.entite.Adresse_$$_javassist_0.toString(Adresse_$$_javassist_0.java)
    	at java.lang.String.valueOf(String.java:2615)
    	at java.lang.StringBuilder.append(StringBuilder.java:116)
    	at cnam.entite.test.ClientBeanTest.main(ClientBeanTest.java:44)
    Si dans mon entité client, je mets "fetch=EAGER", le code s'exécute correctement. Ce qui est logique puisque l'adresse est chargée lors de la récupération des clients.

    En résumé, je ne vois pas comment gérer proprement les lazy loading dans mon programme client. Je ne me vois pas mettre les fetch à EAGER sur toute mes associations (aie les performances). Et créer des méthodes dans mes EJB du style "Adresse getAdresse(Client cli)" me semble bien lourd.
    Je me dis que je suis passé à coté de quelques choses, mais je ne vois pas ce que c'est. Et les cours que j'ai pu trouver ici et là ne parle quasiment pas de ce problème.

    Le reste de ma configuration : JBoss AS 4.2 + hibernate +mysql

    Merci d'avance pour votre aide.

  2. #2
    Membre éclairé Avatar de bassim
    Homme Profil pro
    Ingénieur Réseaux
    Inscrit en
    Février 2005
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 666
    Points : 695
    Points
    695
    Par défaut
    Bonsoir,
    Juste une question : est ce normal que les deux serialVersionUID des deux classes soient égaux ?

    Et si tu mettais des valeurs différentes, ça donne quoi ?
    Where is my mind

  3. #3
    Membre éprouvé

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    733
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 733
    Points : 1 119
    Points
    1 119
    Par défaut
    Bonjour, merci de ta réponse,.
    Citation Envoyé par bassim Voir le message
    Bonsoir,
    Juste une question : est ce normal que les deux serialVersionUID des deux classes soient égaux ?
    Ils sont issus de la génération de code par eclipse, je ne les ai pas modifiés.

    Et si tu mettais des valeurs différentes, ça donne quoi ?
    Je n'ai pas le code sous la main pour tester, je te donnerai le résultat avec cette modification dés que je le pourrais.

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    733
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 733
    Points : 1 119
    Points
    1 119
    Par défaut
    Suite de mon histoire.

    Afin de conserver le lazy loading, j'ai implémenter des méthodes(genre "getFullPersonFromId(int id)") dans mes ejb qui s'occupe de précharger ces données.
    Avec ce genre de méthode cela fonctionne.


    Si il y a une meilleure méthode pour procéder, je suis preneur.

  5. #5
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Bonjour,
    Et si tu ajoutes type = PersistenceContextType.EXTENDED comme second attribut à ton annotation @PersistenceContext ... ça marche dans le serveur, mais je n'en suis pas sûr pour un client distant ...

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    733
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 733
    Points : 1 119
    Points
    1 119
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Bonjour,
    Et si tu ajoutes type = PersistenceContextType.EXTENDED comme second attribut à ton annotation @PersistenceContext ... ça marche dans le serveur, mais je n'en suis pas sûr pour un client distant ...
    J'avais essayé une fois de mettre cette options, mais le déploiement échouait.

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

Discussions similaires

  1. [1.x] Symfony 1.4 : sortable et column_aggregation sont sur un bateau
    Par NickoX9 dans le forum Symfony
    Réponses: 1
    Dernier message: 13/05/2013, 23h38
  2. Réponses: 1
    Dernier message: 31/10/2012, 15h50
  3. Hibernate, Polymorphisme, et Select sont sur un bateau.
    Par andlio dans le forum Hibernate
    Réponses: 0
    Dernier message: 23/08/2011, 00h13
  4. [EJB3] Retour null sur tous mes EJB Stateless.
    Par vinzo dans le forum Java EE
    Réponses: 3
    Dernier message: 06/02/2007, 16h28
  5. Réponses: 1
    Dernier message: 07/04/2005, 13h31

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