Oui ca serait vraiment super !! Merci de ton soutient DevServlet... Et s'il vous faut quelque chose de plus je vous le donne..
Je vous donne tout un élément de mon architecture. Par exemple pour pays. Il faudrait que je puisse récupérer les localités de ce pays qui sont actuellement annotées avec un @XmlTransient et que je ne peux récupérer :
Service REST :
Manager de pays :
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 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package service; import ch.plugin.sportreserv.BusinessService.local.PaysManagerLocal; import ch.plugin.sportreserv.entity.Pays; import java.util.List; import javax.ejb.EJB; import javax.ejb.Stateless; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; /** * * @author Chatis */ @Stateless @Path("pays") public class PaysFacadeREST{ @EJB PaysManagerLocal pays; @POST @Consumes({"application/json"}) //@Consumes({"application/xml", "application/json"}) public void create(String entity){ } @GET @Produces({"application/json", "application/xml"}) public List<Pays> findAll() { return pays.getAllPays(); } @GET @Path("{id}") @Produces({"application/json", "application/xml"}) public Pays find(@PathParam("id") Integer id) { return pays.find(id); } }
DAO de pays (ou les find, findAll, edit, create sont stockées la classe AbstractFacade):
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 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package ch.plugin.sportreserv.BusinessService; import ch.plugin.sportreserv.BusinessService.local.PaysManagerLocal; import ch.plugin.sportreserv.dao.local.PaysFacadeLocal; import ch.plugin.sportreserv.entity.Pays; import java.util.List; import javax.ejb.EJB; import javax.ejb.Stateless; /** * * @author Chatis */ @Stateless public class PaysManager implements PaysManagerLocal { @EJB PaysFacadeLocal pays; public List<Pays> getAllPays() { return this.pays.findAll(); } public Pays find(int id) { return this.pays.find(id); } }
et mon entitée (avec le @XmlTransient sur mon entitée sinon : LazyInitializeException):
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 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package ch.plugin.sportreserv.dao; import ch.plugin.sportreserv.dao.local.PaysFacadeLocal; import ch.plugin.sportreserv.entity.Pays; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; /** * * @author Chatis */ @Stateless public class PaysFacade extends AbstractFacade<Pays> implements PaysFacadeLocal { @PersistenceContext(unitName = "SportReserv-PU") private EntityManager em; protected EntityManager getEntityManager() { return em; } public PaysFacade() { super(Pays.class); } }
Merci pour votre aide
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
151
152
153 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package ch.plugin.sportreserv.entity; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; /** * * @author Chatis */ @Entity @Table(name = "pays") @XmlRootElement public class Pays implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Basic(optional = false) @Column(name = "IDPays") private Integer iDPays; @Column(name = "NomPays", length= 20) private String nomPays; @Column(name = "RegexNPA", length=40) private String regexNPA; @Column(name = "ExempleNPA", length=10) private String exempleNPA; @Column(name = "RegexTelephone", length=70) private String regexTelephone; @Column(name = "ExempleTelephone", length=20) private String exempleTelephone; @Column(name = "InternationalPays", length=3) private String internationalPays; @OneToMany(mappedBy="pays") private List<Localite> localites; public Pays() { } public Pays(Integer iDPays) { this.iDPays = iDPays; } public Integer getIDPays() { return iDPays; } public void setIDPays(Integer iDPays) { this.iDPays = iDPays; } public String getNomPays() { return nomPays; } public void setNomPays(String nomPays) { this.nomPays = nomPays; } public String getRegexNPA() { return regexNPA; } public void setRegexNPA(String regexNPA) { this.regexNPA = regexNPA; } public String getRegexTelephone() { return regexTelephone; } public void setRegexTelephone(String regexTelephone) { this.regexTelephone = regexTelephone; } public String getInternationalPays() { return internationalPays; } public void setInternationalPays(String internationalPays) { this.internationalPays = internationalPays; } public void addLocalite(Localite Localite){ this.localites.add(Localite); Localite.setPays(this); } public String getExempleNPA() { return exempleNPA; } public void setExempleNPA(String exempleNPA) { this.exempleNPA = exempleNPA; } public String getExempleTelephone() { return exempleTelephone; } public void setExempleTelephone(String exempleTelephone) { this.exempleTelephone = exempleTelephone; } @XmlTransient public List<Localite> getLocalites() { return localites; } public void setLocalites(List<Localite> localites) { this.localites = localites; } @Override public int hashCode() { int hash = 0; hash += (iDPays != null ? iDPays.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 Pays)) { return false; } Pays other = (Pays) object; if ((this.iDPays == null && other.iDPays != null) || (this.iDPays != null && !this.iDPays.equals(other.iDPays))) { return false; } return true; } @Override public String toString() { return "ch.plugin.sportreserv.entity.Pays[ iDPays=" + iDPays + " ]"; } }
Et par la même occasion, comment je fais dans votre cas, pour rajouter en même temps un pays et ses localités ? dans le cas ou je fais "em.persist(pays)" (ou "em.merge(pays)" s'il est existant mais que je rajoute des localités) pour que les localités présentent dans cette objet se rajoutent également..
J'aurais vraiment besoin que vous m'aidiez un petit peu s'il vous plait....
Un petit up car toujours pas de solution.... :-( ... Si quelqu'un d'autre connait la solution décrite par JeitEmgie... faites signesmerci
je ne sais pas si cela va t'aider, mais j'ai le même problème,mais pas avec les même conf d'appli que toi. je suis sur du struts, hibernate, annotation JPA.
Lors de la préparation d'objet ayant des list en vue de sauvegarde en base même erreur. après 7 mois de recherche la seul solution viable que j'ai trouvé, c'est de faire un select par l'ID avant manipulation de l'objet , pour chaque formulaire, page web ou autre. Ce qui force l'application a rattacher l'objet à mon entitymanager, je n'ai plus de problème de session close. Ce n'ai pas sexy et optimisé mais ça marche pour moi.
l'entitymanager gère toutes mes requêtes sur la base.
Merci !! Mais malheureusement ca ne m'aide pas plus... j'ai essayé cette solution mais ca ne change rien... car le problème intervient après toute intervention sur mes objets lors de la sérialisation en JSON ou XML. C'est a ce moment qu'il essaye d'appeler toutes mes collections liées à l'objet alors que je ne veux pas ça. Et je n'ai encore trouver aucun moyen de le faire et je suis toujours bloqué.
Actuellement je me démerde avec des associations monodirectionnel mais c'est pas très beau et ca m'oblige a appeler plusieurs fois les mêmes objets.. Ca fait vraiment pas professionnel et ca bouffe pas mal de ressources.. C'est pourquoi j'aimerais VRAIMENT avoir un peu plus de développement de la solution JeitEmgie qui me plait bien car elle permet de sortir seulement les éléments qu'on veut.. Mais je ne sais vraiment pas comment la faire :-(
Apparemment je suis pas le seul avec ce problème...
http://community.jboss.org/thread/102439
quelques idées ??
Je suis tombé sur cette solution.. Mais je l'ai testée mais ca ne marche pas.. quelqu'un à une idée pourquoi ??
http://java.net/jira/browse/JAXB-280
Il ne passe jamais dans HibernateAccessor....
Bonjour,
Etant donné que j'ai pas trop envie de décortiquer 4 pages de messages, tu pourrais résumer la situation ?
Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
Ceylon : Installation - Concepts de base - Typage - Appels et arguments
ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
Une solution vous convient ? N'oubliez pas le tag
Signature par pitipoisson
Ok alors pour résumé :
J'ai une application avec interface utilisateur en PHP qui appelle un service web REST en Java qui lui même utilise Hibernate pour appeler la base de données.
Le problème vient des entités avec des relations @OneToMany ou @ManyToMany qui ne sont pas chargées au moment de les transférer à l'interface PHP. Java essaye de récupérer toutes ses relations à la place de les changer en "null" et récupérer toutes ses relations non chargées provoque une erreur de type "LazyInitializeException" (exactement le même problème que le lien que j'ai donné ci-dessus sur le site de jboss.org)
Actuellement pour éviter ce problème, j'ai placé des annotations @XmlTransient sur toutes ses relations mais il m'est impossible de travailler avec dans PHP vu qu'elles ne sont pas reconnu au moment de la transformation. Alors je dois revenir à une programmation relationnelle
Si tu veux voir ce que ça donne au niveau code, le message "chatis 21/06/2011 13h38" de cette discussion contient un exemple complet de mon architecture du côté Java.
Merci
Sans la stack cela peut peut provenir de plusieurs origines mais en général c'est un problème de session JPA/Hibernate qui est fermée.
Marquer les attributs/accesseurs en XML Transient fait que les objets ne sont pas "sérialiser" dans la réponse de ton WebService !
Ce n'est donc pas une solution.
Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
Ceylon : Installation - Concepts de base - Typage - Appels et arguments
ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
Une solution vous convient ? N'oubliez pas le tag
Signature par pitipoisson
Pour le @XmlTransient je sais mais ca sa ca ne marche pas....
Oui les sessions sont fermées, mais je ne demande pas des les rouvrir ! je veux juste que si j'ai pas appelé la relation, qu'il la mette à NULL a la place d'essayer de la récupérer et de faire une erreur de LazyInitializeException... Il y a un moyen de faire ca ?
Si tu ne veux pas des valeurs alors pourquoi les sérialiser ?
Que tu renvoies "null" ou que la propriété soit "transient", ca ne change pas énormément.
Sinon :
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 package service; import ch.plugin.sportreserv.BusinessService.local.PaysManagerLocal; import ch.plugin.sportreserv.entity.Pays; import java.util.List; import javax.ejb.EJB; import javax.ejb.Stateless; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; /** * * @author Chatis */ @Stateless @Path("pays") public class PaysFacadeREST{ @EJB PaysManagerLocal pays; @POST @Consumes({"application/json"}) //@Consumes({"application/xml", "application/json"}) public void create(String entity){ } @GET @Produces({"application/json", "application/xml"}) public List<Pays> findAll() { List<Pays> allPays = pays.getAllPays(); for (Pays pays : allPays) { allPays.setLocalites(null); } return allPays; } @GET @Path("{id}") @Produces({"application/json", "application/xml"}) public Pays find(@PathParam("id") Integer id) { Pays found = pays.find(id); found.setLocalites(null); return found; } }
Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
Ceylon : Installation - Concepts de base - Typage - Appels et arguments
ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
Une solution vous convient ? N'oubliez pas le tag
Signature par pitipoisson
Ben le problème se trouve exactement là !!! C'est que des fois j'ai besoins des localités et des fois je n'en ai pas besoin....
Si j'en ai pas besoin et que je fais "pays.setLocalite(null)" ca me modifie également dans la BDD.
Si je veux récupérer les localités ben ca marche jamais car j'ai l'erreur LazyInitializeException qui apparait.
Comment faire pour que ca marche tout le temps ?
Si je fais : return pays.getAll(), il ne faudrait pas qu'il me récupère les localités.
Si je fais : pays.getAll(); for(Pays p : pays); p.getLocalite(); return pays, il me récupère les localités
Vu que tu n'en as pas besoin tout le temps, il ne faut pas tout le temps faire la même chose
Soit tu désactives complétement le fetch et tu demandes à ton DAO de te charger la liste à la demande.
Soit tu laisses le lazy :
- Quand tu n'en as pas besoin, tu forces à "null" pour "désactiver" le fetch.
- Quand tu en as besoin, tu demandes la taille de la "relation"
Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
Ceylon : Installation - Concepts de base - Typage - Appels et arguments
ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
Une solution vous convient ? N'oubliez pas le tag
Signature par pitipoisson
Désolé ca fait longtemps, mais forcer de mettre les collections à null ça ne marche pas... Pourquoi ? Car il me supprime toutes les relations dans la BDD par la même occasion même si je ne confirme pas avec un merge ou un flsuh..... Je suis PERDU !
J'ai déjà eu ce problème mais c'était en utilisant spring-hibernate.
Sinon tu as pensé à utiliser SessionFactory.openStatelessSession() ?
EDIT : En relisant quelques posts précédents, je me rappelle que tu passes par un EJB, c'est peut-être JPA/JTA qui sont configurés pour sauvegardés tes objets et comitté à la fin du traitement ?
Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
Ceylon : Installation - Concepts de base - Typage - Appels et arguments
ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
Une solution vous convient ? N'oubliez pas le tag
Signature par pitipoisson
Mais je ne dois pas utilisé de SessionFactory avec JPA/JTA c'est juste ? En tout cas je ne crois pas que ca s'utilise avec une appli java EE 6 il me semble...
Et où c'est que je peux voir si c'est JPA/JTA qui est configuré comme cela... dans GlassFish lors de la configuration de ma pool.. je me souviens avoir mis quelque chose pour les transaction qui était "read-commited" mais je ne sais pas si c'est ca dont tu parles...
Sinon je ne pense pas que j'ai fait autre chose pour configurer les JPA/JTA...
merci
Partager