使用ManyToMany注释时,Rest响应有问题。 问题是这个答案:
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"])
没有ManyToMany注释(就像在Model类Role中一样)我响应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 :(得分:0)
问题在于序列化用户实体的属性角色。在RoleService中加载实体然后将结果返回给控制器时,hibernate会话结束。你无法在hibernate会话之外加载它。
您也不能急切地加载这些属性。然后就有机会加载大型物体树。
在我看来,要解决你的问题,你必须创建3个REST服务和3个正常的服务方法来加载平面数据结构:
另外,您必须使用注释@JsonIgnore注释您的集合属性(角色,用户),以便在序列化到json期间忽略它们。