简体   繁体   English

杰克逊JSON和延迟加载的集合

[英]Jackson JSON and lazy loaded collections

I have a class which lazy loads a collection. 我有一类懒加载一个集合。 Now I have two different Queries, one that loads the data without the collection and another which loads the whole data. 现在,我有两个不同的查询,一个查询在不收集数据的情况下加载数据,另一个在查询整个数据。 When executing the Query which doesn't load the collection I get the following error: 当执行不加载集合的查询时,出现以下错误:

JsonMappingException: failed to lazily initialize a collection of role: Player.goals

I tried to fix that with using the @JsonInclude(JsonInclude.Include.NON_EMPTY) annotation but that didn't help. 我试图通过使用@JsonInclude(JsonInclude.Include.NON_EMPTY)批注来修复此问题,但这没有帮助。

How do I produce two different JSON Results based on the same Class? 如何基于同一个类产生两个不同的JSON结果?

Update: Updated the structure and added JSONView but the error didn't change. 更新:更新了结构并添加了JSONView,但错误没有改变。

Model 模型

@Entity
public class User implements Serializable {
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
    private Collection<Team> teams = new ArrayList<Team>();
}

@Entity
public class Team implements Serializable {
  ...
  @OneToMany(cascade = CascadeType.ALL, mappedBy = "team", targetEntity = Player.class, fetch = FetchType.EAGER)
  @JsonView(UserViews.User.class)
  private Collection<Player> players = new ArrayList<Player>();
  ...
}

@Entity
public class Player implements Serializable {
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "player", targetEntity = Goal.class, fetch = FetchType.LAZY)
    @JsonView(UserViews.UserWithGoals.class)
    private Collection<Goal> goals= new ArrayList<Goal>();
...
}

Queries 查询

@Query("SELECT u FROM User u WHERE u.id = :id")
Team findById(@Param("id") Long id);

Spring Controller 弹簧控制器

@RequestMapping(headers = "Accept=application/json")
@JsonView(UserViews.User.class)
public @ResponseBody Team getTeam(Authentication authentication) {
    User user = userService.findById(1);

    return team;
}

With this configuration accessing the controller shouldn't load the Goals of the Player class, but that's exactly the mentioned part in the JSONMappingException. 通过这种配置访问,控制器不应加载Player类的Goals ,但这正是JSONMappingException中提到的部分。 Any idea what's wrong? 知道有什么问题吗?

Maybe you can take a look to Jackson JsonViews : http://wiki.fasterxml.com/JacksonJsonViews . 也许您可以看看Jackson JsonViews: http ://wiki.fasterxml.com/JacksonJsonViews。

You will have to define two different views in your entity: 您将必须在实体中定义两个不同的视图:

@Entity
public class Team implements Serializable {
    ...
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "team", targetEntity = Player.class, fetch = FetchType.LAZY)
    @JsonView(FullView.class)
    private Collection<Player> players = new ArrayList<Player>();
    ...
}

and activate the view in you caller method (typically you JAX-RS implementation - see http://wiki.fasterxml.com/JacksonJsonViews#Views_with_JAX-RS ) 并在调用方方法中激活视图(通常是JAX-RS实现-请参见http://wiki.fasterxml.com/JacksonJsonViews#Views_with_JAX-RS

Doing this, the players list will be ignore in the first case and serialized in JSON only if the list is filled. 这样做,播放器列表在第一种情况下将被忽略,并且仅在列表被填充时才以JSON序列化。

Syntax should not be correct, sorry, but you got the idea 语法不正确,对不起,但您明白了

To prevent lazy you can configure in Spring the OpenEntityManagerInVew filter in xml or in java (don't remember the exact syntax): 为了防止延迟,您可以在Spring中配置xml或java中的OpenEntityManagerInVew过滤器(不记得确切的语法):

<filter>
    <filter-name>openEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>        
</filter>

<filter-mapping>
    <filter-name>openEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Hope it helps 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM