2015-10-11 171 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期間忽略它們。