2015-05-13 4 views
1

Было 2 дня, когда я пытался решить проблему сериализации json в моем проекте, где у меня есть группа классов сущностей, сопоставленных друг с другом с отношениями «один ко многим». Таким образом, ошибкаspring mvc (HATEOS) - ошибка сериализации jackson json

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.softcons.cas.entities.CASWeightageMaster.casQuestionMaster, could not initialize proxy - no Session (through reference chain: com.softcons.cas.rest.CASQuestionMasterResource["casQuestionDescriptions"]->org.hibernate.collection.internal.PersistentBag[0]->com.softcons.cas.entities.CASQuestionDescription["casQuestionMaster"]->com.softcons.cas.entities.CASQuestionMaster["casWeightageMaster"]->com.softcons.cas.entities.CASWeightageMaster["casQuestionMaster"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.softcons.cas.entities.CASWeightageMaster.casQuestionMaster, could not initialize proxy - no Session (through reference chain: com.softcons.cas.rest.CASQuestionMasterResource["casQuestionDescriptions"]->org.hibernate.collection.internal.PersistentBag[0]->com.softcons.cas.entities.CASQuestionDescription["casQuestionMaster"]->com.softcons.cas.entities.CASQuestionMaster["casWeightageMaster"]->com.softcons.cas.entities.CASWeightageMaster["casQuestionMaster"]) 
    org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.writeInternal(MappingJackson2HttpMessageConverter.java:244) 
    org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:207) 
    org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:148) 
    org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:125) 
    org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71) 
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) 
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749) 
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:690) 
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) 
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945) 
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) 
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) 
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:617) 
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316) 
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126) 
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:168) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) 
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53) 
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) 
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) 
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) 
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 

Там один-ко-многим между QuestionMaster & QuestionDescription также между QuestionMaster & Weightage мастер сущностей есть много-к-одному. Мне нужно получить одну запись в QuestionMaster со списком встроенных записей QuestionDescription. Для этого я сделал FetchType как нетерпеливый между QuestionMaster & QuestionDescription, все правильно работали, прежде чем я представил этот List<QuestionDescription> в качестве ресурса для преобразования json. Я продолжаю получать вышеуказанную ошибку. Не знаю, где изменить, поскольку я пытался все, что мог найти в Интернете.

question_master

@Entity 
    @Table(name = "cas_question_master") 
    public class CASQuestionMaster extends BasicEntity { 

    private String question; 
    private boolean self; 
    private boolean peer; 
    private boolean supervisor; 
    private boolean subordinate; 
    private boolean deleteFlag; 
    private boolean inactive; 
    private Long deletedBy; 
    private Date deletedOn; 
    private CASWeightageMaster casWeightageMaster; 
    private String questionDef; 
    private List<CASQuestionDescription> casQuestionDescription; 

    @OneToMany(targetEntity = CASQuestionDescription.class, mappedBy = "casQuestionMaster", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    public List<CASQuestionDescription> getCasQuestionDescription() { 
     return casQuestionDescription; 
    } 

    public void setCasQuestionDescription(
      List<CASQuestionDescription> casQuestionDescription) { 
     this.casQuestionDescription = casQuestionDescription; 
    } 

    @Column(name = "question", length = 2000) 
    public String getQuestion() { 
     return question; 
    } 

    public void setQuestion(String question) { 
     this.question = question; 
    } 

    @ManyToOne(fetch=FetchType.EAGER) 
    @JoinColumn(name = "weightage_id_fk", nullable = false) 
    public CASWeightageMaster getCasWeightageMaster() { 
     return casWeightageMaster; 
    } 

    public void setCasWeightageMaster(CASWeightageMaster casWeightageMaster) { 
     this.casWeightageMaster = casWeightageMaster; 
    } 
    } 

question_description

@Entity 
@Table(name = "cas_question_description") 
public class CASQuestionDescription extends BasicEntity { 

private CASQuestionMaster casQuestionMaster; 
private String Description; 
private boolean deleteFlag; 
private Long deletedBy; 
private Date deletedOn; 

@ManyToOne 
@JoinColumn(name="question_id_fk", nullable=false) 
public CASQuestionMaster getCasQuestionMaster() { 
    return casQuestionMaster; 
} 
public void setCasQuestionMaster(CASQuestionMaster casQuestionMaster) { 
    this.casQuestionMaster = casQuestionMaster; 
} 

@Column(name="description", nullable=false) 
public String getDescription() { 
    return Description; 
} 
public void setDescription(String description) { 
    Description = description; 
} 

} 

weightage_master

@Entity 
    @Table(name = "cas_weightage_master") 
    public class CASWeightageMaster extends BasicEntity { 
    private int weightage; 
    private List<CASQuestionMaster> casQuestionMaster; 

    @Column(name = "weightage", nullable=false) 
    public int getWeightage() { 
     return weightage; 
    } 

    public void setWeightage(int weightage) { 
     this.weightage = weightage; 
    } 

    @OneToMany(targetEntity = CASQuestionMaster.class, mappedBy = "casWeightageMaster", cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    public List<CASQuestionMaster> getCasQuestionMaster() { 
     return casQuestionMaster; 
    } 

    public void setCasQuestionMaster(List<CASQuestionMaster> casQuestionMaster) { 
     this.casQuestionMaster = casQuestionMaster; 
    } 

    } 

код контроллера

@RequestMapping(value="/findAll", method=RequestMethod.GET) 
    public ResponseEntity<CASQuestionMasterListResource> findAll() 
    { 
     try { 
      CASQuestionMasterList casQuestionMasterList = new CASQuestionMasterList();    
      casQuestionMasterList.setCasQuestionMasterList(casQuestionMasterService.findAll());    
      CASQuestionMasterListResource res = new CASQuestionMasterListAsm().toResource(casQuestionMasterList); 
      return new ResponseEntity<CASQuestionMasterListResource>(res, HttpStatus.OK); 
     } catch(Exception exception) 
     { 
      throw new NotFoundException(exception); 
     } 
    } 

Я использовал Spring HATEOS для формата json. Ниже приведен файл ресурсов, используемый для преобразования в json. Ниже перечислены файлы ресурсов, используемые для преобразования JSon

QuestionMasterResource

public class CASQuestionMasterResource extends ResourceSupport { 

private Long questionId; 
private String question; 
private Long casWeightageMasterId; 

private List<CASQuestionDescription> casQuestionDescriptions; 

public List<CASQuestionDescription> getCasQuestionDescriptions() { 
    return casQuestionDescriptions; 
} 
public void setCasQuestionDescriptions(
     List<CASQuestionDescription> casQuestionDescriptions) { 
    this.casQuestionDescriptions = casQuestionDescriptions; 
} 
public String getQuestion() { 
    return question; 
} 
public Long getQuestionId() { 
    return questionId; 
} 
public void setQuestionId(Long questionId) { 
    this.questionId = questionId; 
} 
public void setQuestion(String question) { 
    this.question = question; 
} 

public Long getCasWeightageMasterId() { 
    return casWeightageMasterId; 
} 
public void setCasWeightageMasterId(Long casWeightageMaster) { 
    this.casWeightageMasterId = casWeightageMaster; 
} 


public CASQuestionMaster toQuestionMaster(CASWeightageMaster casWeightageMaster){ 

    CASQuestionMaster casQuestionMaster = new CASQuestionMaster(); 

    casQuestionMaster.setId(this.questionId); 
    casQuestionMaster.setCasWeightageMaster(casWeightageMaster); 
    casQuestionMaster.setQuestion(this.question); 

    return casQuestionMaster; 
} 

} 

QuestionMasterListResource

public class CASQuestionMasterListResource extends ResourceSupport { 
    private List<CASQuestionMasterResource> casQuestionMasterResources = new ArrayList<CASQuestionMasterResource>(); 

    public List<CASQuestionMasterResource> getCasQuestionMasterResources() { 
     return casQuestionMasterResources; 
    } 

    public void setCasQuestionMasterResources(
      List<CASQuestionMasterResource> casQuestionMasterResources) { 
     this.casQuestionMasterResources = casQuestionMasterResources; 
    } 

    } 

QuestionMasterList ассемблер

public class CASQuestionMasterListAsm extends ResourceAssemblerSupport<CASQuestionMasterList, CASQuestionMasterListResource>{ 

    public CASQuestionMasterListAsm() { 
     super(CASQuestionMasterController.class, CASQuestionMasterListResource.class); 
    } 

    @Override 
    public CASQuestionMasterListResource toResource(CASQuestionMasterList casQuestionMasterList) { 
     List<CASQuestionMasterResource> casQuestionMasterResources = new CASQuestionMasterAsm().toResources(casQuestionMasterList.getCasQuestionMasterList()); 
     CASQuestionMasterListResource casQuestionMasterListResource = new CASQuestionMasterListResource(); 
     casQuestionMasterListResource.setCasQuestionMasterResources(casQuestionMasterResources); 
     return casQuestionMasterListResource;  
    } 
    } 

Конечная нота при входе, чтобы проверить записи на мастер вопрос объект загружается с нетерпением он ведет журнал. На самом деле не получается, где я ошибаюсь.

ответ

0

Сериализация JSON может инициировать выборку коллекции, и поскольку в этот момент у вас нет сеанса спящего режима, вы получаете исключение.

Вы можете управлять этим процессом с помощью jackson-datatype-hibernate, Документах объяснить, как бы вы настроить его

public class HibernateAwareObjectMapper extends ObjectMapper { 

    public HibernateAwareObjectMapper() { 
     registerModule(new Hibernate4Module()); 
    } 
} 

чем зарегистрировать

<mvc:annotation-driven> 
     <mvc:message-converters> 
      <!-- Use the HibernateAware mapper instead of the default --> 
      <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
       <property name="objectMapper"> 
        <bean class="path.to.your.HibernateAwareObjectMapper" /> 
       </property> 
      </bean> 
     </mvc:message-converters> 
    </mvc:annotation-driven> 

Модуль имеет Feature.FORCE_LAZY_LOADING настройки, что указывает, должен ли объект быть загружен, а затем сериализован, который по умолчанию установлен на false. Эта настройка означает, что вы не получите исключение, но также и то, что список не будет включен в ответ json.

Если вы хотите использовать список в ответе, вы можете инициализировать его в своем коде в том месте, где у вас есть действующий сеанс, как в службах, путем вызова, например. Hibernate.initialize(casQuestionMaster.getCasQuestionDescription()) или даже лучше просто вызвать любое свойство списка, например. getCasQuestionDescription().size(), или установите для FORCE_LAZY_LOADING значение true, но это попытается загрузить все лениво загруженные коллекции.

+0

спасибо за ответ ур. Мастер-ведомый, с вашим своевременным ответом, я смог решить вышеупомянутую проблему и добавить к вашему ответу, если мы используйте '@ JsonManagedReference' и' @ JsonBackReference' для двунаправленных сопоставлений, с которыми мы можем столкнуться в stackoverflowerror ... проверьте эту ссылку ... http: //www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion ... и спасибо много снова .. :) – Amit

+0

рад, что у вас есть проблема, и хороший комментарий, хорошая ссылка для будущих посетителей, стоящих перед проблемой –

Смежные вопросы