2015-10-11 37 views
1

我在使用ManyToMany注释时遇到Rest响应问题。 问题是这样的答案:Spring Data Rest FetchType

Problem accessing /json2/1. Reason: 

    Server Error 

Caused by: 

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.Tomek.entity.User.roles, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.Tomek.entity.Role["users"]->org.hibernate.collection.internal.PersistentBag[0]->com.Tomek.entity.User["roles"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.Tomek.entity.User.roles, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.Tomek.entity.Role["users"]->org.hibernate.collection.internal.PersistentBag[0]->com.Tomek.entity.User["roles"]) 

没有多对多注释(如在Model类角色)我响应JSON格式

[{"id":1,"name":"ROLE_USER"},{"id":2,"name":"ROLE_ADMIN"}] 

RestController

@Controller 
public class RestController { 

    @Autowired 
    private UserService userService; 

    @Autowired 
    private BlogService blogService; 

    @Autowired 
    private RoleService roleService; 

@RequestMapping("/json") 
    public String JsonLink(Model model){ 
     model.addAttribute("result", blogService.findAll()); 
     return "json"; 
    } 

    @RequestMapping(value = "/json2/{id}", method = RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE) 
    public @ResponseBody List<Role> ShowJson(@PathVariable int id) { 
     Hibernate.initialize(roleService.findAll()); 
     List<Role> role = roleService.findAll(); 
     System.out.println(role.toString()); 
     return role; 
    } 

模范作用(评论@ManyToMany)

@Entity 
@JsonAutoDetect 
public class Role { 

    @Id 
    @GeneratedValue 
    private Integer id; 

    private String name; 

    /*@ManyToMany(fetch = FetchType.EAGER,mappedBy = "roles") 
    private List<User> users; 

    public List<User> getUsers() { 
     return users; 
    } 

    public void setUsers(List<User> users) { 
     this.users = users; 
    }*/ 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public Role(String name) { 
     this.name = name; 
    } 
    public Role() { 
    } 

    @Override 
    public String toString() { 
     return "Role [id=" + id + ", name=" + name + "]"; 
    } 
} 

型号用户

@Entity 
@JsonAutoDetect 
public class User { 

    @Id 
    @GeneratedValue 
    private Integer id; 

    private String name; 

    private String email; 

    private String password; 

    private boolean enabled; 

    @ManyToMany 
    @JoinTable 
    private List<Role> roles; 

    @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE) 
    private List<Blog> blogs; 

    public boolean isEnabled() { 
     return enabled; 
    } 

    public void setEnabled(boolean enabled) { 
     this.enabled = enabled; 
    } 

    public List<Blog> getBlogs() { 
     return blogs; 
    } 

    public void setBlogs(List<Blog> blogs) { 
     this.blogs = blogs; 
    } 

    public List<Role> getRoles() { 
     return roles; 
    } 

    public void setRoles(List<Role> roles) { 
     this.roles = roles; 
    } 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getEmail() { 
     return email; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

} 

服务

@Service 
public class RoleService { 

    @Autowired 
    private RoleRepository roleRepository; 

    public List<Role> findAll(){ 
     return roleRepository.findAll(); 
    } 

JSP

<c:forEach items="${result}" var="item"> 
<a href="<spring:url value="/json2/${item.id}" />">json</a> 

</c:forEach> 

回答

0

问题是与用户实体的序列化属性的作用。当你在RoleService中加载实体,然后将结果返回给控制器时,休眠会话结束。您无法在休眠会话之外加载它。

您也无法加载这些属性。然后会有机会加载大树的对象。

在我看来,解决您的proplem你必须创建3个REST服务和3个正常的服务方法,该方法将加载扁平的数据结构:

  1. /角色/(编号) - 它加载单个角色(没有用户财产)
  2. /roles/{id}/users - 它加载所有具有给定id(无角色属性)角色的用户
  3. /users/{id}/roles - 它为给定ID的用户加载角色

A dditionaly你必须使用注解@JsonIgnore来注释你的集合属性(角色,用户),以在序列化为json期间忽略它们。