2014-11-16 15 views
7

Buduję usługę RESTful Web Service, która pobiera i zwraca JSON. Podczas próby pobrania obiektu ESRBRating z bazy danych za pośrednictwem warstwy usługi napotykam następujący ślad stosu. Jednak, gdy wstrzyknę do repozytorium Spring Data JPA bezpośrednio do kontrolera i użyję go do pobrania ESRBRating by ID, to działa dobrze. Jednak podczas wywoływania przez warstwę usługi nie działa. Podałem poniżej stos kodu i kodu stosu. Czy ktoś może mi wyjaśnić, dlaczego tak się dzieje podczas przechodzenia przez warstwę usługi, ale nie podczas bezpośredniego przeglądania repozytorium Spring Data JPA? Jak rozwiązać ten problem?JsonMappingException: nie można zainicjować proxy - brak sesji

Śledzenie stosu

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 

Controller

@RestController 
@RequestMapping(produces = "application/json", value="/esrbrating") 
public class ESRBRatingController { 

    @Inject 
    ESRBRatingService esrbRatingService; 

    @Inject 
    ESRBRatingRepository esrbRatingRepository; 

    private Logger logger = LoggerFactory.getLogger(getClass()); 

    /** 
    * Returns all ESRB ratings in database 
    * 
    * @return List of ESRBRating objects 
    * @see ESRBRating 
    */ 
    @RequestMapping(value = {"","/"}, method = RequestMethod.GET) 
    public ResponseEntity<List<ESRBRating>> getESRBRatings() { 
     List<ESRBRating> esrbRatings = esrbRatingService.getESRBRatings(); 
     return new ResponseEntity<>(esrbRatings, HttpStatus.OK); 
    } 

    /** 
    * Returns a single ESRB rating object if exists, otherwise returns HTTP status code 404 
    * 
    * @param id ID of the ESRB Rating 
    * @return ESRB Rating when found 
    * @see ESRBRating 
    */ 
    @RequestMapping(value = "/{id}", method = RequestMethod.GET) 
    public ResponseEntity<?> getUser(@PathVariable("id") Long id) { 
     logger.debug("Attempting to fetch ESRB rating with ID: {}", id); 
     ESRBRating esrbRating = esrbRatingService.getESRBRating(id); 
     //ESRBRating esrbRating = esrbRatingRepository.findOne(id); 

     if (esrbRating == null) { 
      return new ResponseEntity<>("ESRB Rating not found", HttpStatus.NOT_FOUND); 
     } else { 
      return new ResponseEntity<>(esrbRating, HttpStatus.OK); 
     } 
    } 

} 

usługi

@Service 
@Transactional 
public class ESRBRatingServiceImpl implements ESRBRatingService { 

    @Value("#{paging.games.maxPageSize}") 
    private static int DEFAULT_PAGE_SIZE; 

    @Value("#{paging.games.maxPageSize}") 
    private static int MAX_PAGE_SIZE; 

    @Inject 
    private ESRBRatingRepository esrbRatingRepository; 

    @Override 
    public List<ESRBRating> getESRBRatings() { 
     List<ESRBRating> ratings = esrbRatingRepository.findAll(); 
     return ratings; 
    } 

    @Override 
    public ESRBRating getESRBRating(Long id) { 
     return esrbRatingRepository.getOne(id); 
    } 

    @Override 
    public ESRBRating saveESRBRating(ESRBRating esrbRating) { 
     return esrbRatingRepository.saveAndFlush(esrbRating); 
    } 

    @Override 
    public boolean deleteESRBRating(Long id) { 
     esrbRatingRepository.delete(id); 
     return true; 
    } 
} 

Repository

package net.jkratz.igdb.repository; 

import net.jkratz.igdb.model.ESRBRating; 

import org.springframework.data.jpa.repository.JpaRepository; 

public interface ESRBRatingRepository extends JpaRepository<ESRBRating, Long> { 

} 

Model

@Entity 
@Table(name = "esrb_rating", schema = "igdb") 
@JsonIgnoreProperties(ignoreUnknown = true) 
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; 
    } 

    @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(); 
    } 
} 

Ten kod kontrolera działa poprawnie, przechodząc bezpośrednio przez repozytorium.

@RestController 
@RequestMapping(produces = "application/json", value="/esrbrating") 
public class ESRBRatingController { 

@Inject 
ESRBRatingService esrbRatingService; 

@Inject 
ESRBRatingRepository esrbRatingRepository; 

private Logger logger = LoggerFactory.getLogger(getClass()); 

/** 
* Returns all ESRB ratings in database 
* 
* @return List of ESRBRating objects 
* @see ESRBRating 
*/ 
@RequestMapping(value = {"","/"}, method = RequestMethod.GET) 
public ResponseEntity<List<ESRBRating>> getESRBRatings() { 
    List<ESRBRating> esrbRatings = esrbRatingService.getESRBRatings(); 
    return new ResponseEntity<>(esrbRatings, HttpStatus.OK); 
} 

/** 
* Returns a single ESRB rating object if exists, otherwise returns HTTP status code 404 
* 
* @param id ID of the ESRB Rating 
* @return ESRB Rating when found 
* @see ESRBRating 
*/ 
@RequestMapping(value = "/{id}", method = RequestMethod.GET) 
public ResponseEntity<?> getUser(@PathVariable("id") Long id) { 
    logger.debug("Attempting to fetch ESRB rating with ID: {}", id); 
    ESRBRating esrbRating = esrbRatingRepository.findOne(id); 

    if (esrbRating == null) { 
     return new ResponseEntity<>("ESRB Rating not found", HttpStatus.NOT_FOUND); 
    } else { 
     return new ResponseEntity<>(esrbRating, HttpStatus.OK); 
    } 
} 

}

UPDATE:

Śledziłem porady Randall Harleigh i ustawić odwrotną kolekcję @JsonIgnore. Jednak teraz otrzymuję zupełnie inny ślad stosu. Wygląda na to, że Jackson/Spring nie wie jak serializować ESRBRating. Wszelkie wskazówki na ten temat?

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 

Aktualizacja 2:

skończyło się na oddanie @Proxy (leniwy = false) od klasy ESRBRating i teraz działa dobrze. Jednak jestem ciekawy, jaki wpływ na wydajność może mieć to działanie?

@Entity 
@Table(name = "esrb_rating", schema = "igdb") 
@JsonIgnoreProperties(ignoreUnknown = false) 
@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; 
    } 


    @JsonIgnore 
    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(); 
    } 
} 

Na wniosek tutaj jest klasa Gra

@Entity 
@Table(name = "game", schema = "igdb", 
     indexes = {@Index(name = "idx_game_title", columnList = ("title"), unique = false), 
       @Index(name = "idx_game_developer", columnList = ("developer"), unique = false), 
       @Index(name = "idx_game_publisher", columnList = ("publisher"), unique = false)}) 
@JsonIgnoreProperties(ignoreUnknown = true) 
public class Game 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(name = "description", length = 65535) 
    private String description; 

    @Size(max = 255) 
    @Column(name = "developer", length = 255) 
    private String developer; 

    @Size(max = 255) 
    @Column(name = "publisher", length = 255) 
    private String publisher; 

    @NotNull 
    @Size(max = 4) 
    @Column(name = "players", nullable = false) 
    private short players; 

    @NotNull 
    @Column(name = "cooperative", nullable = false) 
    private boolean cooperative; 

    @NotNull 
    @Column(name = "release_date", nullable = false) 
    @Temporal(TemporalType.DATE) 
    private Date releaseDate; 

    @Size(max = 255) 
    @Column(name = "image", length = 255) 
    private String image; 

    @JoinColumn(name = "esrb_rating_id", referencedColumnName = "id", nullable = false) 
    @ManyToOne(optional = false, fetch = FetchType.EAGER) 
    private ESRBRating esrbRating; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "game") 
    private List<GamePlatformMap> gamePlatformMap; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "game") 
    private List<GameGenreMap> gameGenreMap; 

    public Game() { 

    } 

    public Game(Long id, String title, String description, String developer, 
      String publisher, short players, boolean cooperative, 
      Date releaseDate, String image, ESRBRating esrbRating) { 
     super(); 
     this.id = id; 
     this.title = title; 
     this.description = description; 
     this.developer = developer; 
     this.publisher = publisher; 
     this.players = players; 
     this.cooperative = cooperative; 
     this.releaseDate = releaseDate; 
     this.image = image; 
     this.esrbRating = esrbRating; 
    } 

    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 String getDeveloper() { 
     return developer; 
    } 

    public void setDeveloper(String developer) { 
     this.developer = developer; 
    } 

    public String getPublisher() { 
     return publisher; 
    } 

    public void setPublisher(String publisher) { 
     this.publisher = publisher; 
    } 

    public short getPlayers() { 
     return players; 
    } 

    public void setPlayers(short players) { 
     this.players = players; 
    } 

    public boolean isCooperative() { 
     return cooperative; 
    } 

    public void setCooperative(boolean cooperative) { 
     this.cooperative = cooperative; 
    } 

    public Date getReleaseDate() { 
     return releaseDate; 
    } 

    public void setReleaseDate(Date releaseDate) { 
     this.releaseDate = releaseDate; 
    } 

    public String getImage() { 
     return image; 
    } 

    public void setImage(String image) { 
     this.image = image; 
    } 

    public ESRBRating getEsrbRating() { 
     return esrbRating; 
    } 

    public void setEsrbRating(ESRBRating esrbRating) { 
     this.esrbRating = esrbRating; 
    } 

    @JsonIgnore 
    public List<GamePlatformMap> getGamePlatformMap() { 
     return gamePlatformMap; 
    } 

    public void setGamePlatformMap(List<GamePlatformMap> gamePlatformMap) { 
     this.gamePlatformMap = gamePlatformMap; 
    } 

    @JsonIgnore 
    public List<GameGenreMap> getGameGenreMap() { 
     return gameGenreMap; 
    } 

    public void setGameGenreMap(List<GameGenreMap> gameGenreMap) { 
     this.gameGenreMap = gameGenreMap; 
    } 

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

     Game that = (Game) o; 

     return Objects.equal(this.id, that.id) && 
       Objects.equal(this.title, that.title) && 
       Objects.equal(this.description, that.description) && 
       Objects.equal(this.developer, that.developer) && 
       Objects.equal(this.publisher, that.publisher) && 
       Objects.equal(this.players, that.players) && 
       Objects.equal(this.cooperative, that.cooperative) && 
       Objects.equal(this.releaseDate, that.releaseDate) && 
       Objects.equal(this.image, that.image) && 
       Objects.equal(this.esrbRating, that.esrbRating); 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hashCode(id, title, description, developer, publisher, players, 
       cooperative, releaseDate, image, esrbRating); 
    } 

    @Override 
    public String toString() { 
     return Objects.toStringHelper(this) 
       .add("id", id) 
       .add("title", title) 
       .add("description", description) 
       .add("developer", developer) 
       .add("publisher", publisher) 
       .add("players", players) 
       .add("cooperative", cooperative) 
       .add("releaseDate", releaseDate) 
       .add("image", image) 
       .add("esrbRating", esrbRating) 
       .toString(); 
    } 
} 
+0

@Proxy (lazy = false) to oszczędza moje dni dzięki. –

+0

@ André Luís Tomaz Dionisio - Dzięki! Twoja sugestia wykonuje zadanie :) – MAC

Odpowiedz

26

Zazwyczaj zdarza się to, gdy wracają do obiektu poprzez @Responsebody (lub w przypadku odpowiedzi organizmu drodze @RestController) i obiekt jest jest serializowany, ale ma dzieci w kolekcji LAZY, które nie zostały przywołane. Do czasu, gdy jesteś w swoim kontrolerze, nie ma już aktywnej transakcji, która ułatwiłaby ich pobieranie (tak jak to, które zacząłeś w swojej @Service). Możesz albo wykonać swoją strategię pobierania EAGER, wprowadzić swoje kolekcje przez odniesienie, gdy wciąż znajdujesz się w transakcji, albo zrobić LAZY kolekcje JSON Transient.

+0

Dobrze, więc @JsonIgnore pracował przy niezinicjowanej kolekcji, jednak teraz dostaję błąd o serializacji. Wszelkie pomysły na moim ostatnim śladzie stosu. Zaktualizowałem moje pytanie ze szczegółami. – greyfox

+0

Zwykle dzieje się tak, ponieważ klasa, która chce być serializowana, ma prywatne pola bez publicznych programów pobierających i ustawiających. Nie wydaje się, aby tak było w tym przypadku. Ponadto - gdzie są gry? Zanim przejdziemy do kłopotów, próbując to debugować, tylko dla śmiechu, umieść @JsonSerialize na deklaracji klasy dla ESRBRating. Przyjmij też moją odpowiedź na pierwszy numer. –

+0

Jeśli używasz późniejszego Jacksona, będzie to @JsonInclude (Include.NON_NULL) –

6

Najpierw pobierz jackson-datatype-hibernate4-2.2.3.jar lub nowszą wersję zgodnie z wersją jackson-core. Następnie użyj tego kodu w pliku konfiguracyjnym i możesz użyć strategii pobierania LAZY bez żadnego błędu.

import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.datatype.hibernate4.Hibernate4Module; 


public class ApplicationConfig extends WebMvcConfigurerAdapter 
{ 
public MappingJackson2HttpMessageConverter jacksonMessageConverter(){ 
    MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter(); 

    ObjectMapper mapper = new ObjectMapper(); 
    //Registering Hibernate4Module to support lazy objects 
    mapper.registerModule(new Hibernate4Module()); 

    messageConverter.setObjectMapper(mapper); 
    return messageConverter; 

} 

@Override 
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
    //Here we add our custom-configured HttpMessageConverter 
    converters.add(jacksonMessageConverter()); 
    super.configureMessageConverters(converters); 
} 
1

@JsonIgnore adnotacja może rozwiązać problem, ale powoduje, że szczególną dziedziną, która początkowo ustawiony jako FetchType.LAZY być całkowicie ignorowane.Lepsza jest tutaj https://stackoverflow.com/a/21760361/3609067

Powiązane problemy