Java @许多人发起LazyInitializationException异常

Java @许多人发起LazyInitializationException异常,java,hibernate,jpa,many-to-many,lazy-evaluation,Java,Hibernate,Jpa,Many To Many,Lazy Evaluation,出于某些测试目的,我试图让JUnit测试抛出LazyInitializationException 我的情况是,我有3个实体 @Entity(name = "Role") public class Role { @LazyCollection(LazyCollectionOption.TRUE) @ManyToMany(mappedBy = "roles", fetch=FetchType.LAZY) private Set<AppUser> appUsers

出于某些测试目的,我试图让JUnit测试抛出LazyInitializationException

我的情况是,我有3个实体

@Entity(name = "Role")
public class Role {
    @LazyCollection(LazyCollectionOption.TRUE)
    @ManyToMany(mappedBy = "roles", fetch=FetchType.LAZY)
    private Set<AppUser> appUsers;
    ...

}

@Entity(name = "Group")
public class Group {
    @LazyCollection(LazyCollectionOption.TRUE)
    @ManyToMany(mappedBy = "groups", fetch=FetchType.LAZY)
    private Set<AppUser> appUsers;
    ...
}

@Entity(name = "AppUser")
public class AppUser {
    @LazyCollection(LazyCollectionOption.TRUE)
    @ManyToMany(fetch= FetchType.LAZY)
    @JoinTable(name = "APPUSER_ROLE", joinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "ROLE_ID", referencedColumnName = "ID"))
    private Set<Role> roles;
    ...

    @LazyCollection(LazyCollectionOption.TRUE)
    @ManyToMany(fetch= FetchType.LAZY)
    @JoinTable(name = "APPUSER_GROUP", joinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "GROUP_ID", referencedColumnName = "ID"))
    private Set<Group> groups;
    ...

} 
@实体(name=“Role”)
公共阶级角色{
@LazyCollection(LazyCollectionOption.TRUE)
@ManyToMany(mappedBy=“roles”,fetch=FetchType.LAZY)
私有用户集;
...
}
@实体(名称=“集团”)
公共课组{
@LazyCollection(LazyCollectionOption.TRUE)
@ManyToMany(mappedBy=“groups”,fetch=FetchType.LAZY)
私有用户集;
...
}
@实体(name=“AppUser”)
公共类AppUser{
@LazyCollection(LazyCollectionOption.TRUE)
@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(name=“APPUSER\u ROLE”,joinColumns=@JoinColumn(name=“USER\u ID”,referencedColumnName=“ID”),inverseJoinColumns=@JoinColumn(name=“ROLE\u ID”,referencedColumnName=“ID”))
私人设定角色;
...
@LazyCollection(LazyCollectionOption.TRUE)
@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(name=“APPUSER\u GROUP”,joinColumns=@JoinColumn(name=“USER\u ID”,referencedColumnName=“ID”),inverseJoinColumns=@JoinColumn(name=“GROUP\u ID”,referencedColumnName=“ID”))
私有集合组;
...
} 
我生成了一些测试数据,其中所有这3个数据都正确地保存在数据库中。然后我提交事务

但随后我尝试使用相同的测试方法来读取
角色
(基于id),但我也读取了所有其他相关实体(似乎被急切地加载)。为什么会这样?我怎样才能进入
懒散初始化异常

编辑:好的,我对一般描述不感兴趣,而是需要一个代码示例,因为我无法启动它。一般描述并不能解决我的问题

我怎么来懒散

如果您有:

  • 延迟加载的实体成员(如一个OneToMany或多个)
  • 没有活动事务(实体已分离)
  • 成员尚未加载
  • 您尝试访问实体成员,这将触发延迟加载,但由于实体已分离,因此不可能
  • 我怎么来懒散

    如果您有:

  • 延迟加载的实体成员(如一个OneToMany或多个)
  • 没有活动事务(实体已分离)
  • 成员尚未加载
  • 您尝试访问实体成员,这将触发延迟加载,但由于实体已分离,因此不可能

  • 问题在于,即使我在测试方法中提交了事务,我也必须关闭EntityManager并再次打开它,以在设置中触发
    LazyInitializationException

    最后,我得到了以下实体代码:

    @Entity(name = "Role")
    public class Role {
        @ManyToMany(mappedBy = "roles")
        private Set<AppUser> appUsers;
        ...
    
    }
    
    @Entity(name = "Group")
    public class Group {
        @ManyToMany(cascade = {CascadeType.PERSIST})
        @JoinTable(name = "GROUP_APPUSER", joinColumns = @JoinColumn(name = "GROUP_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"))
        private Set<AppUser> appUsers;
        ...
    }
    
    @Entity(name = "AppUser")
    public class AppUser {
        @ManyToMany(cascade = {CascadeType.PERSIST})
        @JoinTable(name = "APPUSER_ROLE", joinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "ROLE_ID", referencedColumnName = "ID"))
        private Set<Role> roles;
        ...
    
        @ManyToMany(mappedBy = "appUsers")
        private Set<Group> groups;
        ...
    
    } 
    
    即使很难,也没有必要这样做,因为已经在1.st延迟加载(
    Group->AppUser
    )上发生了延迟问题

    而测试代码本身,最重要的部分是:

    em.getTransaction().begin();
    em.persist(group);
    em.getTransaction().commit();
    em.close();
    
    // reinit em
    ...
    
    // load group from DB and afterwards close em
    em.close();
    ...
    // following throws LazyInitializationException :)
    group.getAppUsers().iterator().next();
    

    问题在于,即使我在测试方法中提交了事务,我也必须关闭EntityManager并再次打开它,以在设置中触发
    LazyInitializationException

    最后,我得到了以下实体代码:

    @Entity(name = "Role")
    public class Role {
        @ManyToMany(mappedBy = "roles")
        private Set<AppUser> appUsers;
        ...
    
    }
    
    @Entity(name = "Group")
    public class Group {
        @ManyToMany(cascade = {CascadeType.PERSIST})
        @JoinTable(name = "GROUP_APPUSER", joinColumns = @JoinColumn(name = "GROUP_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"))
        private Set<AppUser> appUsers;
        ...
    }
    
    @Entity(name = "AppUser")
    public class AppUser {
        @ManyToMany(cascade = {CascadeType.PERSIST})
        @JoinTable(name = "APPUSER_ROLE", joinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "ROLE_ID", referencedColumnName = "ID"))
        private Set<Role> roles;
        ...
    
        @ManyToMany(mappedBy = "appUsers")
        private Set<Group> groups;
        ...
    
    } 
    
    即使很难,也没有必要这样做,因为已经在1.st延迟加载(
    Group->AppUser
    )上发生了延迟问题

    而测试代码本身,最重要的部分是:

    em.getTransaction().begin();
    em.persist(group);
    em.getTransaction().commit();
    em.close();
    
    // reinit em
    ...
    
    // load group from DB and afterwards close em
    em.close();
    ...
    // following throws LazyInitializationException :)
    group.getAppUsers().iterator().next();
    

    感谢您的回答,但即使我尝试从DB加载em.detach(role),它仍然包含AppUser引用到role。所以,似乎所有的东西都被急切地加载了,即使我期望它被懒洋洋地加载。我觉得我的映射(注释)有问题。谢谢您的回答,但即使我尝试从DB加载em.detach(role),它仍然包含AppUser引用到role。所以,似乎所有的东西都被急切地加载了,即使我期望它被懒洋洋地加载。我觉得我的映射(注释)有问题。