Question

J'utilise Spring MVC, AJAX / JSON et Hibernate pour obtenir toutes les personnes à partir d'une base de données MySQL. J'ai écrit des tests d'intégration JUnit pour vérifier mon service et tout est correct.

Maintenant, je l'appelle dans ce genre:

@RequestMapping(value="/allpersons", method=RequestMethod.GET)
public @ResponseBody Set<Person> getAllPersons() {
    Set<Person> persons= new PersonServiceImpl().getAllPersons();
    return persons;
}

Je déboguée il. La ligne avec

return persons;

tout va bien. J'ai un HashSet avec toutes les personnes en elle. Débogage plusieurs étapes, je viens à cette ligne:

this.objectMapper.writeValue(jsonGenerator, o);

org.springframework.http.converter.json.MappingJacksonHttpMessageConverter

Je ne vois pas le code source, mais mon débogueur me dit:

StdSerializerProvider._serializeValue(JsonGenerator, Object) line 297

Après cette ligne, je reçois l'erreur:

ERROR: org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: com.mydomain.project.dom.Person.projects, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.mydomain.project.dom.Person.projects, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
    at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)
    at org.codehaus.jackson.map.ser.ContainerSerializers$CollectionSerializer.serializeContents(ContainerSerializers.java:339)
    at org.codehaus.jackson.map.ser.ContainerSerializers$CollectionSerializer.serializeContents(ContainerSerializers.java:314)
    at org.codehaus.jackson.map.ser.ContainerSerializers$AsArraySerializer.serialize(ContainerSerializers.java:112)
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:268)
    at org.codehaus.jackson.map.ser.BeanSerializer.serializeFields(BeanSerializer.java:160)
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:131)
    at org.codehaus.jackson.map.ser.ContainerSerializers$CollectionSerializer.serializeContents(ContainerSerializers.java:363)
    at org.codehaus.jackson.map.ser.ContainerSerializers$CollectionSerializer.serializeContents(ContainerSerializers.java:314)
    at org.codehaus.jackson.map.ser.ContainerSerializers$AsArraySerializer.serialize(ContainerSerializers.java:112)
    at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:297)
    at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:224)
    at org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:1030)
    at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.writeInternal(MappingJacksonHttpMessageConverter.java:153)
    at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:181)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.writeWithMessageConverters(AnnotationMethodHandlerAdapter.java:975)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.handleResponseBody(AnnotationMethodHandlerAdapter.java:933)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.getModelAndView(AnnotationMethodHandlerAdapter.java:882)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:428)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
    at org.tuckey.web.filters.urlrewrite.NormalRewrittenUrl.doRewrite(NormalRewrittenUrl.java:195)
    at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:159)
    at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:141)
    at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:90)
    at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:417)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)

Il semble, qui a quelque chose à voir avec la sérialisation / JacksonMapping. Il veut obtenir les projets associés d'une personne, qui ne sont pas nécessaires et ils sont normalement chargés paresseusement.

Quel est le problème ici?

Merci à l'avance et meilleures salutations.

Était-ce utile?

La solution

Qu'est-ce que vous rencontrez est similaire avec ceci:

En un mot, vous accédez à une collection lazy-chargée en dehors de la session Mise en veille prolongée.

Solutions possibles:

      
  • chercher avidement
  •   
  • assurez-vous que votre session Hibernate est encore ouvert au moment où vous accédez à la collection. Vous pouvez utiliser le filtre OpenSessionInView. Cela en soi peut ne pas être suffisant, comme Hibernate peut mettre fin à votre session où vous fermez votre transaction. Vous aurez donc besoin d'étendre votre champ d'opération ou de trouver un moyen d'empêcher Hibernate de fermer la session sur la fin de l'opération.
  •   
  • assurez-vous d'accéder à la collection lazy-chargée dans votre transaction, pour vous assurer que les charges Hibernate il.

S'il vous plaît vérifier le montant indiqué ci-dessus pour plus de détails.

UPDATE 1 D'après ce que je comprends, cela est causé par le cartographe Jackson recevant un modèle qui n'a pas été complètement chargé (certaines collections sont chargées paresseux). Vous dites que vous n'avez pas besoin des objets dans ces collections à cartographier par Jackson. Les alternatives que je vois sont:

  • Donner Jackson un modèle correct, POJO simples créées en fonction de vos objets Personne, ne contenant que les informations que vous souhaitez mapper avec Jackson. Ainsi, au lieu de donner Jackson une liste des personnes, vous allez donner une liste de PersonDetails (ou comme vous voulez les appeler)
  • Configurer Jackson pour ignorer cette collection - pas sûr que ce soit possible

Hope this helps.

Autres conseils

Bien que cela ne pas immédiatement vous aider avec la facilité, il peut être bon de savoir qu'il ya un nouveau projet lié Jackson, jackson-module-veille prolongée (à GitHub) qui vise à résoudre ce problème ainsi que d'autres cas d'utilisation souvent problématique.

Mais à court terme, vous trouverez peut-être cet article utile: http://kyrill007.livejournal.com/ 2577.html

Si vous ne voulez pas la carte en vous êtes la objet JSON le champ qui est lié en relation avec mise en veille prolongée, vous pouvez ajouter des annotations « @JsonIgnore » dans votre classe de modèle:

@JsonIgnore
@OneToMany(mappedBy = "person")
private List<ProjectEntity> projects = new ArrayList<ProjectEntity>();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top