vous ne répondez toujours pas à la simple question : comment gérez-vous les transactions ?
Version imprimable
Tu peux y aller en requête ObjetTestes voir les gets sur les resultats retournés par cette requete pour voir si les entités associées sont préchargées. et redis nousCode:select maClasseA from ClassA maClasseA
Mais les getters sont préchargés... Dans ma méthode RESTFul, je peux afficher les id de mes collections. Mais au moment de l'envoyer à mon client PHP, j'ai cette erreur. Lors de la transformation en JSON je pense....
voila la méthode @GET de mon service RESTFul
et voila la sortie de mon printlnCode:
1
2
3
4
5
6
7
8 @GET @Path("{id}") @Produces({"application/json", "application/xml"}) public Pays find(@PathParam("id") Integer id) { Pays p = pays.find(id); System.out.println(p.getLocalites()); return p; }
Donc c'est bien au moment de convertir que ca plante.. je pense que ca vient du @XmlRootElement... car ni en JSON ni en XML ca marche..Code:
1
2 INFO: [ch.plugin.sportreserv.entity.Localite[ iDLocalite=21 ], ch.plugin.sportreserv.entity.Localite[ iDLocalite=24 ]]
Je suis désolé mais je ne peux mieux t'aider que ca, j'avais déjà rencontré un souci pareil en utilisant Dozer, j'avais beau mettre des LAZY, sauf que Dozer quand il avait besoin d'une entité associée, lui meme envoyait hibernate aller me chercher les entités associées. Je te proposerai une derniere solution si jamais tu trouves rien d'autres, c'est vraiment la solution extreme extreme. En fait que tu casses toutes tes relations OneToMany, et mette simplement des id comme attribut privé pour faire la jointure entre 2 classes. L'avantage c'est que ca resoudra ton pb et du coup plus besoin de EAGER ou LAZY, l'inconvenient c'est que pour avoir les entités associées tu devras lancer forcement une requete plutot. donc continues de chercher, tu trouves rien tu implements celle là.
Merci de ton aide... Mais c'est incroyable qu'il n'y ai pas de moyen de faire ca comme ca... Car ta solution m'est interdite par les contraintes de mon projet qui stipule que je dois travailler entièrement en objet... donc je n'ai pas le droit de travailler avec des id...
De plus faire comme cela ne donne aucun avantage à utiliser Hibernate qui est également une contrainte de mon projet..... alors je suis FICHU :-(
Dans la solution que je te propose , tu restes bien sur en objet, y'a rien de relationnel, mais bon je suis d'accord , c'est pas propre.
Mais comment les gérer si on utilise pas le framework Spring ? je ne trouve que des infos avec spring.. et ca va pouvoir m'aider a récupérer que l'id de ma collection ? a moins que je fasse un get ? merci...
Code:
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 Session session = getSessionFactory().openSession() ; Transaction tx = null ; try { tx = session.beginTransaction() ; do the job tx.commit() ; } catch(Exception e) { if (tx != null) { try { tx.rollback() ; } catch(HibernateExcepiton he) { // log } } throw e ; } finally { try { session.close() ; } catch(HibernateExcepiton he) { throw he ; } }
Voila mon nouveau code :
Mais l'erreur reste la même... LazyInitialiseException..Code:
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 @GET @Produces({"application/json", "application/xml"}) public List<Sport> findAll() throws Exception { List <Sport> sp = null; Session session = HibernateUtil.getSessionFactory().openSession() ; Transaction tx = null ; try { tx = session.beginTransaction() ; sp = sport.getAllSport(); tx.commit() ; } catch(Exception e) { if (tx != null) { try { tx.rollback() ; } catch(Exception he) { throw he; } } throw e ; } finally { try { session.close() ; } catch(Exception he) { throw he ; } } return sp; }
Le problème ne vient pas de la récupération de mes données. mais bien lors de la sérialisation de ceux-ci en xml ou json. Lors de cette étape, l'objet essaye d'aller chercher les objets auxquels il est lié par des collections. Mais je veux juste qu'il me récupère l'ID et qu'il ne va pas plus loins que ca. A moins que j'appelle le getter de la collection avant la sérialisation et dans ce cas il va me rechercher l'objet.
si vous sérialisez en dehors du openSession/closeSession rien d'étonnant qu'il y ait une LazyExceptiion…
Ok alors on avance....
j'ai sérialisé à l'intérieur et maintenant j'ai cette erreur :Code:
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 @GET @Produces({"application/json", "application/xml"}) public String findAll() throws Exception { String sp = null; Session session = HibernateUtil.getSessionFactory().openSession() ; Transaction tx = null ; try { tx = session.beginTransaction() ; Gson g = new Gson(); sp = g.toJson(sport.getAllSport()); tx.commit() ; } catch(Exception e) { if (tx != null) { try { tx.rollback() ; } catch(Exception he) { throw he; } } throw e ; } finally { try { session.close() ; } catch(Exception he) { throw he ; } } return sp; }
Mais entre (), que je fasse comme ci-dessous ou comme ca :Code:
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 ATTENTION: StandardWrapperValve[org.netbeans.rest.application.config.ApplicationConfig]: PWC1406: Servlet.service() for servlet org.netbeans.rest.application.config.ApplicationConfig threw exception java.lang.IllegalStateException: circular reference error Offending field: sport Offending object: preserveType: false, type: class ch.plugin.sportreserv.entity.Sport, obj: ch.plugin.sportreserv.entity.Sport[ iDSport=1 ] at com.google.gson.CircularReferenceException.createDetailedException(CircularReferenceException.java:43) at com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisitor.java:117) at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:69) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120) at com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializationVisitor.java:147) at com.google.gson.JsonSerializationVisitor.addAsChildOfObject(JsonSerializationVisitor.java:127) at com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisitor.java:114) at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:69) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120) at com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:62) at com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:53) at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.serialize(DefaultTypeAdapters.java:643) at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.serialize(DefaultTypeAdapters.java:624) at com.google.gson.JsonSerializationVisitor.findAndInvokeCustomSerializer(JsonSerializationVisitor.java:184) at com.google.gson.JsonSerializationVisitor.visitFieldUsingCustomHandler(JsonSerializationVisitor.java:204) at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:63) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120) at com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:62) at com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:53) at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.serialize(DefaultTypeAdapters.java:643) at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.serialize(DefaultTypeAdapters.java:624) at com.google.gson.JsonSerializationVisitor.findAndInvokeCustomSerializer(JsonSerializationVisitor.java:184) at com.google.gson.JsonSerializationVisitor.visitUsingCustomHandler(JsonSerializationVisitor.java:160) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:101) at com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:62) at com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationContextDefault.java:53) at com.google.gson.Gson.toJsonTree(Gson.java:220) at com.google.gson.Gson.toJson(Gson.java:260) at com.google.gson.Gson.toJson(Gson.java:240) at service.SportFacadeREST.findAll(SportFacadeREST.java:43) 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:1052) at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124) at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5367) at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619) at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:801) at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571) at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162) at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144) 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:862) at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:801) at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:371) at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5339) at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5327) at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214) at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88) at $Proxy2714.findAll(Unknown Source) at service.__EJB31_Generated__SportFacadeREST__Intf____Bean__.findAll(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.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:167) at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:70) at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:279) at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:86) at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:136) at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:74) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1347) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1279) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1229) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1219) at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:419) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699) at javax.servlet.http.HttpServlet.service(HttpServlet.java:848) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98) at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:326) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:227) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:170) at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822) at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719) at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013) at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) at com.sun.grizzly.ContextTask.run(ContextTask.java:71) at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) at java.lang.Thread.run(Thread.java:619) Caused by: com.google.gson.CircularReferenceException: circular reference error at com.google.gson.JsonSerializationVisitor.start(JsonSerializationVisitor.java:61) at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:109) at com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializationVisitor.java:147) at com.google.gson.JsonSerializationVisitor.addAsChildOfObject(JsonSerializationVisitor.java:127) at com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisitor.java:114) ... 96 more
L'erreur reste la même... donc je reviens toujours à mon point de départ qui est :Code:
1
2
3
4
5
6
7
8 @GET @Produces({"application/json", "application/xml"}) public String findAll() throws Exception { Gson g = new Gson(); String sp = g.toJson(sport.getAllSport()); return sp; }
Comment récupérer seulement les ID lorsque mon entité fait appel à d'autres objets par relations ? et récupérer l'objet en entier si je fait appel à son getter ? et non récupérer tout l'objet lors de la sérialisation désérialisation....
pour ne pas sérialiser toute la DB, vous devez avoir entre vos objets de la DB et votre UI, une couche de "façade" qui sait ce qui doit être transmis à l'UI et ce sont les objets de façade qui sont sérialisés.
C'est aussi au niveau de cette couche que vous pourrez plus tard ajouter par exemple du filtrage de sécurité (en lignes et/ou en colonnes).
Et cette couche de service de "façade", fera les queries (éventuellement natifs) pour ne récupérer que les champs à sérialiser…
Avez-vous un exemple de comment faire ca ? car c'est exactement ce que j'ai... un service REST, qui redirige l'appel vers un Manager, qui lui appel le DAO pour récupérer ce que j'ai besoin... Mais je ne sais pas comment faire pour lui dire de récupérer seulement ce que j'ai besoin sans qu'il prenne tous les objets des relations... Ca m'aiderait GRANDEMENT !!! Car le problème dur depuis bien longtemps !!! Encore merci...
faut croire que non : ce n'est pas ce que avez, sinon vous n'auriez pas de problème…
votre service REST doit faire appel à un service "Façade" qui sait comment convertir un objet brut de la DB en un objet "façade" ne contenant que ce qui doit être sérialisé (et donc éviter les cycles et les lazy…), ce service "Façade" est soit d'une nouvelle taxonomie (et utilisera Manager comme un "delegate" pour les opérations d'accès au Repository), soit tout simplement il fait partie d'une taxonomie de ce que vous appelez "Manager" et donc il sait par nature comment accéder au "Repository"…
(et donc au lieu de renvoyer des objets Sport il renverra des objets SportFacade complètement détachés de la gestion ORM…)