2014-11-18 9 views
6

Ero di fronte a due tracce di stack diverse (vedi sotto) quando provo a serializzare il mio oggetto ESRBRating che è un'entità JPA. Sto usando Spring Data JPA. Il controller chiamava il servizio, servizio chiamato repository. Sono stato in grado di risolvere il problema aggiungendo @Proxy (lazy = false) sul mio oggetto ESRBRating.Cosa fa l'annotazione di Hibernate @Proxy (lazy = false)?

La mia domanda principale è cosa fa effettivamente @Proxy (lazy = false)? Perché funziona quando lo aggiungi? Questa è una buona soluzione o avrà effetti collaterali come problemi di prestazioni/memoria?

Per riferimento, questa è la mia classe ESRBRating ora.

@Entity 
@Table(name = "esrb_rating", schema = "igdb") 
@JsonIgnoreProperties(ignoreUnknown = true) 
@Proxy(lazy = false) 
public class ESRBRating implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @NotNull 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id", nullable = false) 
    private Long id; 

    @NotNull 
    @Size(min = 1, max = 255) 
    @Column(name = "title", nullable = false, length = 255) 
    private String title; 

    @Size(max = 65535) 
    @Column(length = 65535) 
    private String description; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "esrbRating") 
    private List<Game> games; 

    public ESRBRating() { 
    } 

    public ESRBRating(Long id, String title, String description) { 
     this.id = id; 
     this.title = title; 
     this.description = description; 
    } 

    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    public List<Game> getGames() { 
     return games; 
    } 

    public void setGames(List<Game> games) { 
     this.games = games; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     ESRBRating that = (ESRBRating) o; 

     return Objects.equal(this.id, that.id) && 
       Objects.equal(this.title, that.title) && 
       Objects.equal(this.description, that.description); 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hashCode(id, title, description); 
    } 

    @Override 
    public String toString() { 
     return Objects.toStringHelper(this) 
       .add("id", id) 
       .add("title", title) 
       .add("description", description) 
       .toString(); 
    } 
} 

dello stack:

Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session 
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165) 
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286) 
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) 
    at net.jkratz.igdb.model.ESRBRating_$$_jvst319_0.getId(ESRBRating_$$_jvst319_0.java) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:466) 
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639) 
    ... 76 more 

mi è stato anche sempre questa traccia dello stack.

org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)) (through reference chain: net.jkratz.igdb.model.ESRBRating_$$_jvstb5c_0["handler"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)) (through reference chain: net.jkratz.igdb.model.ESRBRating_$$_jvstb5c_0["handler"]) 
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:238) 
    at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:208) 
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:158) 
    at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:138) 
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:155) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)) (through reference chain: net.jkratz.igdb.model.ESRBRating_$$_jvstb5c_0["handler"]) 
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:59) 
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:26) 
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:505) 
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639) 
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152) 
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:114) 
    at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:1887) 
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:231) 
    ... 72 more 

riferimento alla mia domanda iniziale e problema: JsonMappingException: could not initialize proxy - no Session

risposta

7

@Proxy(lazy=false) disabiliterà il default lazy loading per una particolare entità. Ciò significa che si ottiene sempre l'entità inizializzata ogni volta che questa entità viene referenziata da altre entità.

L'utilizzo di questa annotazione è solitamente un "odore di codice". Se fossi in te, lo rimuoverei e caricare semplicemente tutte le associazioni di entità utilizzando la direttiva join fetch come spiegato in this article.

+0

Quindi @Proxy (lazy = false) farà sì che i giochi nella mia classe ESRBRating vengano caricati automaticamente ogni volta? Questo sarebbe sicuramente un problema perché ogni ESRBRating avrà migliaia di giochi. O non lo capisco correttamente? Se metto fetch = FETCHTYPE.LAZY in @OneToMany, lo sovrascriverà? Quando si recupera ESRBRating dall'API REST, i giochi non verranno mai restituiti nella realtà. – greyfox

+0

Tutte le associazioni di ToMany sono pigri per impostazione predefinita, quindi non sono le raccolte di giochi che verranno recuperate con entusiasmo. È il ESRBRating da prendere con entusiasmo ogni volta che fai riferimento ad altre entità, come quando un gioco ha un'associazione @ManyToOne ESRBRating. In questo caso il Game.ESRBRating non sarà un proxy ma un vero oggetto recuperato. –

+0

Ahhh okay, questo ha senso, quindi in tal caso se l'entità di gioco ha @ManyToOne (opzionale = false, fetch = FetchType.LAZY) per esrbRating e/o il getter ha un @JSONIgnore, continuerà a recuperare l'oggetto ESRBRating? – greyfox

Problemi correlati