我有一个懒惰加载集合的类。现在我有两个不同的查询,一个加载没有集合的数据,另一个加载整个数据。执行不加载集合的Query时,我收到以下错误:
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);
Spring Controller
@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中提到的部分。知道什么是错的吗?
答案 0 :(得分: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>
希望有所帮助