【问题标题】:Solution for JsonMappingException: lazily initialize a collection without using @JsonignoreJsonMappingException 的解决方案:不使用@Jsonignore 懒惰地初始化一个集合
【发布时间】:2015-08-19 09:48:55
【问题描述】:

我需要响应 JSON 作为输出。但它显示了异常

org.codehaus.jackson.map.JsonMappingException: failed to lazily initialize a collection of role: com.sublime.np.entity.User.roles, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.sublime.np.entity.Question["user"]->com.sublime.np.entity.User["roles"])
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218)
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183)
    at org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:140)
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:158)
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446)
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
    at org.codehaus.jackson.map.ser.std.StdContainerSerializers$IndexedListSerializer.serializeContents(StdContainerSerializers.java:122)
    at org.codehaus.jackson.map.ser.std.StdContainerSerializers$IndexedListSerializer.serializeContents(StdContainerSerializers.java:71)
    at org.codehaus.jackson.map.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:86)
    at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)
    at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)
    at org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:1613)
    at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.writeInternal(MappingJacksonHttpMessageConverter.java:209)
    at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:208)
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:143)
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:89)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:193)
    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:749)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)

我在实体之间使用了很多关系。 我的 Qustion 实体看起来像,

@Entity
public class Question {

    @Id
    @GeneratedValue
    private Integer id;

    @Size(min=5, message = "Title must be at least 5 characters !" )
    private String title;

    @Size(min=20, message = "Description must be at least 20 characters !" )
    private String description;

    private int upVote;

    private int downVote;

    @Column(name = "published_date")
    private Date publishedDate;

    @ManyToOne
    @JoinColumn(name="user_id")

    private User user;

    @OneToMany(mappedBy="question", cascade=CascadeType.REMOVE)
    private List<Answer> answers;

    @OneToMany(mappedBy="question", cascade=CascadeType.REMOVE) 
    private List<Comment> comments;

    @ManyToOne
    @JoinColumn(name="tag_id")
    private Tag tag;

当我使用 @JsonIgnore 注释时,它可以工作。但是从我有关系的json字段中消失了。

@OneToMany(mappedBy="question", cascade=CascadeType.REMOVE)
    @JsonIgnore  
    private List<Answer> answers;

    @OneToMany(mappedBy="question", cascade=CascadeType.REMOVE)
    @JsonIgnore  
    private List<Comment> comments;

    @ManyToOne
    @JoinColumn(name="tag_id")
    @JsonIgnore  
    private Tag tag;

使用@JsonIgnore 后的JSON,

[
  {
    "id": 1,
    "title": "ABC",
    "description": "ABC",
    "upVote": 0,
    "downVote": 0,
    "publishedDate": 1433436068000
  },
  {
    "id": 2,
    "title": "SQL Exception",
    "description": "ABC",
    "upVote": 0,
    "downVote": 0,
    "publishedDate": 1433436068000
  }
]

我的控制器,

@RequestMapping(value = "getquestion", method = RequestMethod.GET)
    public @ResponseBody List<Question> getQuestion() {
        List<Question> questions = questionService.getAll();
        return questions;
}

所以,我需要包含所有实体字段的 json。我怎么能得到那个?有什么想法吗?

【问题讨论】:

    标签: java json hibernate jpa jackson


    【解决方案1】:

    【讨论】:

    • 如果我使用 EAGER,它就会变成嵌套的!例如,问题包含用户,用户包含该问题............
    • 是的,那将是显示的结构的直接序列化。你想达到什么目的?
    • 问题有答案列表、评论列表、单个标签、单个用户当我得到问题列表时,每个问题都应该有它的答案列表、评论、标签和用户....不是嵌套
    • 不知道我明白了。您能否就您获得的输出以及您想要的输出提供示例?
    • 切换到 EAGER 是一个糟糕的主意。 LAZY 是一种选择是有原因的。通过将集合切换为 EAGERly 获取来阻塞查询很可能会影响性能
    猜你喜欢
    • 2019-12-17
    • 2011-07-21
    • 2019-01-24
    • 1970-01-01
    • 2018-12-12
    • 1970-01-01
    相关资源
    最近更新 更多