Java Spring数据类型

Java Spring数据类型,java,spring,rest,Java,Spring,Rest,当我使用许多注释时,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.ent

当我使用许多注释时,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"])
如果没有许多注释(如模型类角色中),我将响应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;
    }
@控制器
公共类RestController{
@自动连线
私人用户服务;
@自动连线
私人博客服务;
@自动连线
私人角色服务角色服务;
@请求映射(“/json”)
公共字符串JsonLink(模型){
model.addAttribute(“result”,blogService.findAll());
返回“json”;
}
@RequestMapping(value=“/json2/{id}”,method=RequestMethod.GET,products=MediaType.APPLICATION\u JSON\u value)
public@ResponseBody List ShowJson(@PathVariable int-id){
初始化(roleService.findAll());
List role=roleService.findAll();
System.out.println(role.toString());
返回角色;
}
模范角色(评论@ManyToMany)

@实体
@JsonAutoDetect
公共阶级角色{
@身份证
@生成值
私有整数id;
私有字符串名称;
/*@ManyToMany(fetch=FetchType.EAGER,mappedBy=“roles”)
私人名单用户;
公共列表getUsers(){
返回用户;
}
公共用户(列表用户){
this.users=用户;
}*/
公共整数getId(){
返回id;
}
公共无效集合id(整数id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共角色(字符串名称){
this.name=名称;
}
公共角色(){
}
@凌驾
公共字符串toString(){
返回“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;
    }

}
@实体
@JsonAutoDetect
公共类用户{
@身份证
@生成值
私有整数id;
私有字符串名称;
私人字符串电子邮件;
私有字符串密码;
启用私有布尔值;
@许多
@可接合
私有列表角色;
@OneToMany(mappedBy=“user”,cascade=CascadeType.REMOVE)
私人名单博客;
公共布尔值isEnabled(){
返回启用;
}
已启用公共void集(已启用布尔值){
this.enabled=已启用;
}
公共列表getBlogs(){
返回博客;
}
公共日志(列出日志){
this.blogs=博客;
}
公共列表getRoles(){
返回角色;
}
public void setRoles(列出角色){
this.roles=角色;
}
公共整数getId(){
返回id;
}
公共无效集合id(整数id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共字符串getEmail(){
回复邮件;
}
公用电子邮件(字符串电子邮件){
this.email=电子邮件;
}
公共字符串getPassword(){
返回密码;
}
public void setPassword(字符串密码){
this.password=密码;
}
}
服务

@Service
public class RoleService {

    @Autowired
    private RoleRepository roleRepository;

    public List<Role> findAll(){
        return roleRepository.findAll();
    }
@服务
公共类角色服务{
@自动连线
私人角色扮演者角色扮演者;
公共列表findAll(){
return rolerepositional.findAll();
}
JSP


问题在于序列化用户实体的属性角色。当您在RoleService中加载实体,然后将结果返回控制器时,hibernate会话将结束。您无法在hibernate会话之外加载它

您不能急于加载这些属性。这样就有机会加载大型对象树

在我看来,要解决您的问题,您必须创建3个REST服务和3个普通服务方法,以加载平面数据结构:

  • /roles/{id}-它加载单个角色(没有用户属性)
  • /roles/{id}/users-它加载具有给定id的角色的所有用户(不带roles属性)
  • /users/{id}/roles-它为具有给定id的用户加载角色

  • 此外,还必须对集合属性(角色、用户)进行注释将注释@JsonIgnore序列化为json时忽略它们。

    问题在于序列化用户实体的属性角色。当您在RoleService中加载实体,然后将结果返回给控制器时,hibernate会话将结束。您无法在hibernate会话外加载它

    您不能急于加载这些属性。这样就有机会加载大型对象树

    在我看来,要解决您的问题,您必须创建3个REST服务和3个普通服务方法,以加载平面数据结构:

  • /roles/{id}-它加载单个角色(没有用户属性)
  • /roles/{id}/users-它加载具有给定id的角色的所有用户(不带roles属性)
  • /users/{id}/roles-它为具有给定id的用户加载角色
  • 此外,您还必须使用annotation@JsonIgnore注释集合属性(角色、用户),以便在序列化为json时忽略它们

    @Service
    public class RoleService {
    
        @Autowired
        private RoleRepository roleRepository;
    
        public List<Role> findAll(){
            return roleRepository.findAll();
        }
    
    <c:forEach items="${result}" var="item">
    <a href="<spring:url value="/json2/${item.id}" />">json</a>
    
    </c:forEach>