Frage

Ich bin mit Spring MVC, AJAX / JSON und Hibernate alle Personen aus einer MySQL-Datenbank zu erhalten. Ich schrieb Tests JUnit Integration meinen Dienst zu überprüfen, und alles ist in Ordnung.

Jetzt nenne ich es in dieser Art:

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

Ich gedebuggt es. Die Zeile mit

return persons;

alles ist in Ordnung. Ich habe einen HashSet mit allen Menschen in ihm. Debuggen von mehreren Schritten, komme ich zu dieser Zeile:

this.objectMapper.writeValue(jsonGenerator, o);

in

org.springframework.http.converter.json.MappingJacksonHttpMessageConverter

Dann sehe ich nicht den Quellcode, aber mein Debugger sagt mir:

StdSerializerProvider._serializeValue(JsonGenerator, Object) line 297

Nach dieser Zeile, erhalte ich die Fehlermeldung:

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)

Es scheint, also hat etwas mit der Serialisierung / JacksonMapping zu tun. Sie will die damit verbundenen Projekte einer Person erhalten, die nicht benötigt werden, und sie werden in der Regel träge geladen.

Was ist das Problem hier?

Vielen Dank im Voraus & Mit freundlichen Grüßen.

War es hilfreich?

Lösung

Was Sie begegnen, ist ähnlich mit diesem: Lazy Loading-Fehler

Auf den Punkt gebracht, Sie sind ein fauler-loaded Sammlung außerhalb der Hibernate Session zugreifen.

Mögliche Lösungen:

  • holen sie eifrig
  • stellen Sie sicher, Ihre Hibernate Session ist noch offen an dem Punkt, wo Sie die Sammlung zugreifen. Sie können OpenSessionInView Filter verwenden. Das allein kann nicht genug sein, wie Hibernate kann Ihre Sitzung beenden, wo Sie Ihre Transaktion zu schließen. So müssen Sie Ihren Transaktionsbereich erweitern oder eine Art und Weise zu verhindern, dass Hibernate finden die Sitzung auf Transaktionsende zu schließen.
  • Sie unbedingt die lazy-loaded Sammlung in Ihrer Transaktion zugreifen, um sicherzustellen, dass Hibernate lädt sie zu machen.

Bitte lesen Sie die Post oben angegebenen für weitere Details.

UPDATE 1 Von dem, was ich verstanden habe, was durch den Jackson-Mapper verursacht wird ein Modell erhalten, die nicht vollständig geladen wurde (einige Sammlungen sind faul geladen). Du sagst, du nicht die Objekte in diesen Sammlungen müssen von Jackson abgebildet werden. Die Alternativen ich sehe sind:

  • Geben Jackson ein korrektes Modell, einfache POJOs erstellt auf der Grundlage Ihrer Person Objekte, die nur die Informationen, die Sie mit Jackson zuordnen möchten. Anstatt also gibt Jackson eine Liste von Personen, Sie geben ihm eine Liste von PersonDetails (oder wie Sie wollen, sie nennen)
  • Konfigurieren Jackson dass die Sammlung zu ignorieren - nicht sicher, ob das möglich ist

Hope, das hilft.

Andere Tipps

Während dies nicht sofort Ihnen mit der leicht zu helfen, kann es gut zu wissen, dass es ein neues Jackson-Projekt ist, jackson-module-Hibernate (bei GitHub), den Zielen dieses Problem zusammen mit anderen häufig problematischen Anwendungsfällen zu lösen.

Aber auf kurze Sicht, könnten Sie diesen Artikel nützlich finden: http://kyrill007.livejournal.com/ 2577.html

Wenn Sie nicht in Sie sind JSON-Objekt, das Feld zugeordnet werden soll, die in Hibernate Beziehung verknüpft ist, können Sie Annotations „@JsonIgnore“ in der Modellklasse hinzuzufügen:

@JsonIgnore
@OneToMany(mappedBy = "person")
private List<ProjectEntity> projects = new ArrayList<ProjectEntity>();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top