spring-data-jpa多对多双向关联,查询的时候进入死循环

两个实体类

User

@Data
@Entity
@Table(name = "sys_user")
public class User {
    @Id
    @GeneratedValue
    @Column(name = "user_id")
    private Integer userId;
    @Column(name = "username")
    private String username;
    @ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
    @JoinTable(
            name = "user_role",
            joinColumns = {@JoinColumn(name = "user_id")},
            inverseJoinColumns = {@JoinColumn(name = "role_id")}
    )
    private Set<Role> roles;
}

Role

@Data
@Entity
@Table(name = "sys_role")
public class Role {
    @Id
    @Column(name = "role_id")
    private Integer roleId;
    @Column(name = "role_name", unique = true)
    private String roleName;
    @ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY, mappedBy = "roles")
    private Set<User> users;

测试代码

@Transactional
    @Test
    public void save() throws Exception{
        Set<Role>roles = new HashSet<Role>();
        roles.add(new Role(1, "USER"));
        roles.add(new Role(2, "ADMIN"));

        repository.save(new User("张三", roles));
    }

    @Transactional
    @Test
    public void findAll(){
        List<User> users = repository.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

在使用插入数据的时候没有任何问题,但是当查询的时候报错

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: wang.xiaoqiang.manytomany.entity.User.roles, could not initialize proxy - no Session

这个可以理解,懒加载的时候丢失了session无法获取roles信息,当将user中的集合设置为急加载模式,结果就遇到StackOverflowError

哪位大佬有相关经历,帮帮忙。。。


qq__4787
浏览 10110回答 1
1回答

特南克斯

首先你要理解这是双向关联,双向关联中你如果从数据库里面查询一个User对象,那么User对象里面有Role,Role里面又有User对象,那么你用syso输出User对象,如果toString方法里面包含有输出User.roles的话,那么是必然会造成死循环的。如果你用sping mvc等框架将后台数据返回给前台也是同理,也会造成返回的JSON数据死循环那么要如何解决?解决办法就是在序列化实例的时候中断循环就好。首先你要理解这不是spring-data-jpa的问题,这是一个序列化的问题。例如如果是用jsckson对数据进行序列化的的话,可以使用下面的注解。import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @Data @Entity @Table(name = "sys_user") public class User {     @Id     @GeneratedValue     @Column(name = "user_id")     private Integer userId;     @Column(name = "username")     private String username;     @JsonIgnoreProperties(value = { "users" })     @ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)     @JoinTable(             name = "user_role",             joinColumns = {@JoinColumn(name = "user_id")},             inverseJoinColumns = {@JoinColumn(name = "role_id")}     )     private Set<Role> roles; }这样的话,你再序列化User对象时,user.roles 这个对象中只有 user.roles[i].id 和  users.roles[i].name 而没有 user.roles.users!!!!ok,问题解决!!!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java