2014-10-11 52 views
1

我有一个懒惰加载集合的类。现在我有两个不同的查询,一个加载没有收集的数据,另一个加载整个数据。当执行不加载收集我碰到下面的错误查询:Jackson JSON和懒加载的集合

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

我试图修复与使用@JsonInclude(JsonInclude.Include.NON_EMPTY)注解,但是这并没有帮助。

如何根据相同的类生成两个不同的JSON结果?

更新:更新了结构并添加了JSONView,但错误没有改变。

型号

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

查询

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

春季控制器

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

    return team; 
} 

使用此配置访问控制器不应加载Player类的Goals,但这正是JSONMappingException中提到的部分。任何想法有什么不对?

回答

1

也许你可以看看Jackson JsonViews:http://wiki.fasterxml.com/JacksonJsonViews

你必须定义在实体两种不同的观点:

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

并激活您的观点主叫方法(通常你JAX-RS实现 - 见http://wiki.fasterxml.com/JacksonJsonViews#Views_with_JAX-RS

这样做,玩家列表在第一种情况下将被忽略,并且只有在列表被填充时才以JSON序列化。

语法不应该是正确的,很抱歉,但你有这个想法

为了防止偷懒,你可以在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> 

希望它有帮助

+0

嗯悲伤地,我发布的示例不完整。实际上,我查询了一个急切地加载团队的用户对象。另外Player类还加载了一个集合(懒惰)。在这个结构中,我想我需要调用查询方法并手动创建对象,以便有可能使用@JsonView注释查询方法? 如果这不能说清楚我可以编辑我的原始帖子。 – KenavR 2014-10-11 20:16:51

+0

我不确定是否理解,但实际上,查询方法不能包含@JsonView(我将编辑我的答案)。 JsonView机制允许在实体级别选择要为给定视图序列化哪些字段。然后,您必须在负责序列化的层上激活此视图(通常是JAX-RS的WS层 - 请参阅JsonView文档中的示例) – bmeurant 2014-10-11 20:36:43

+0

感谢至此,我更改了代码,但Exception仍保持不变。我更新了我原来的帖子。顺便说一句,我使用Spring MVC,但我想这应该不重要。 – KenavR 2014-10-11 21:27:49