3

I try query customer list as json from spring controller. when i access url i can get list no error.

-CustomerController

@RequestMapping("getCustomerListRB")
public @ResponseBody List<Customer> getCustomerListsRB() {
    List<Customer> cusList = new ArrayList<Customer>();
    cusList = cusService.getList();
    return cusList;
}

but when i try join table in customer model -Customer.java

   @OneToMany(mappedBy = "Customer", cascade = CascadeType.ALL)
    private List<MainOrder> MainOrder;

    public List<MainOrder> getMainOrder() {
        return MainOrder;
    }
    public void setMainOrder(List<MainOrder> mainOrder) {
        MainOrder = mainOrder;
    }

run server again it have error like bellow:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.mdr.model.Customer.mainOrders, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.mdr.model.Customer["mainOrders"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.mdr.model.Customer.mainOrders, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.mdr.model.Customer["mainOrders"])
    org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.writeInternal(MappingJackson2HttpMessageConverter.java:256)
    org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:208)
    org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:143)
    org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:89)
    org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:193)
    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:689)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    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:622)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

After i add fetch = FetchType.EAGER like below

@OneToMany(mappedBy = "Customer", cascade = CascadeType.ALL,fetch = FetchType.EAGER) 

I run server again it don't have error but can't get data. please help me !

Ma YongChhin
  • 427
  • 3
  • 10
  • 24

3 Answers3

1

First of all, you need a transaction that will last long enough for the Session to be available for lazy fetching of the related entities. In your example, you are returning list of entities with unfetched related entities outside of the Transaction scope (Spring internals will transform List to JSON after the transaction has ended - that is why it fails).

You can do one of the following:

  1. Skip lazyness in your relation since all related entities have to be fetched anyway to prerpare a full JSON response.
  2. Modify your method to be: 'String getCustomerListsRB()' and use an ObjectMapper to serialize 'List' to JSON by yourself (you can autowire ObjectMapper to your controller).
  3. Try to use Open Session In View filter, but I do strongly discourage you from using this approach as it affects performance because database connections are held longer than necessary.
Rafal G.
  • 4,252
  • 1
  • 25
  • 41
1

I got the same exception when using jackson with spring. Add @jsonignore to the field declared as lazy or creating circular dependancy in your entity class. Make sure you use same library's(codehaus/jackson/..) jsonignore in all layers of your application.

tanson
  • 82
  • 3
0

Look at: Spring MVC :could not initialize proxy - no Session (through reference chain:

As a solution you could use addition entity annotation to prevent lazy init

@Entity @Table(name="Country") **@Proxy(lazy = false)** public class Country {}

or use @JsonBackReference in mapping