在使用 SpringBoot + Spring Data JPA + Spring Security 做权限管理的时候,然后当我把one-many,many-one 这些映射关系加上懒加载的时候运行的时候报错。
Could not initialize proxy - no Session
User.java
Authority.java
在启动项目后报错
然后在 CSDN 上看到这样的解释
在 stackoverflow 找到了解决方案
在 application.properties 里添加如下配置,开启懒加载
Could not initialize proxy - no Session
User.java
- package com.liuyanzhao.forum.entity;
- import lombok.Data;
- import org.springframework.security.core.GrantedAuthority;
- import org.springframework.security.core.authority.SimpleGrantedAuthority;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- import org.springframework.security.crypto.password.PasswordEncoder;
- import javax.persistence.*;
- import javax.validation.constraints.Email;
- import javax.validation.constraints.NotEmpty;
- import javax.validation.constraints.Size;
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
- /**
- * @author 言曌
- * @date 2018/3/19 下午9:54
- */
- @Entity
- @Data
- public class User implements UserDetails, Serializable {
- private static final long serialVersionUID = 6147345506206285446L;
- @Id // 主键
- @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增长策略
- private Long id; // 用户的唯一标识
- @NotEmpty(message = "昵称不能为空")
- @Size(min = 2, max = 20, message = "昵称长度必须为2-20个字符")
- @Column(nullable = false, length = 20) // 映射为字段,值不能为空
- private String nickname;
- @NotEmpty(message = "邮箱不能为空")
- @Size(max = 50, message = "邮箱长度不得超过40个字符")
- @Email(message = "邮箱格式不对")
- @Column(nullable = false, length = 50, unique = true)
- private String email;
- @NotEmpty(message = "用户名不能为空")
- @Size(min = 4, max = 20, message = "用户名长度必须为4-20个字符")
- @Column(nullable = false, length = 20, unique = true)
- private String username; // 用户账号,用户登录时的唯一标识
- @NotEmpty(message = "密码不能为空")
- @Size(min = 6, max = 100, message = "密码长度必须为6-100个字符")
- @Column(length = 100)
- private String password; // 登录时密码
- @ManyToMany(cascade = CascadeType.ALL)
- @JoinTable(name = "user_authority",
- joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
- inverseJoinColumns = {@JoinColumn(name = "authority_id", referencedColumnName = "id")}
- )
- private List<Authority> authorities;
- protected User() { // JPA 的规范要求无参构造函数;设为 protected 防止直接使用
- }
- @Override
- public Collection<? extends GrantedAuthority> getAuthorities() {
- // 需将 List<Authority> 转成 List<SimpleGrantedAuthority>,否则前端拿不到角色列表名称
- List<SimpleGrantedAuthority> simpleAuthorities = new ArrayList<>();
- for (GrantedAuthority authority : this.authorities) {
- simpleAuthorities.add(new SimpleGrantedAuthority(authority.getAuthority()));
- }
- return simpleAuthorities;
- }
- public void setAuthorities(List<Authority> authorities) {
- this.authorities = authorities;
- }
- public void setEncodePassword(String password) {
- PasswordEncoder encoder = new BCryptPasswordEncoder();
- String encodePasswd = encoder.encode(password);
- this.password = encodePasswd;
- }
- @Override
- public boolean isAccountNonExpired() {
- return true;
- }
- @Override
- public boolean isAccountNonLocked() {
- return true;
- }
- @Override
- public boolean isCredentialsNonExpired() {
- return true;
- }
- @Override
- public boolean isEnabled() {
- return true;
- }
- }
Authority.java
- package com.liuyanzhao.forum.entity;
- import lombok.Data;
- import org.springframework.security.core.GrantedAuthority;
- import javax.persistence.*;
- import java.util.List;
- /**
- * @author 言曌
- * @date 2018/3/21 下午7:48
- */
- @Entity
- @Data
- public class Authority implements GrantedAuthority {
- private static final long serialVersionUID = 1L;
- @Id // 主键
- @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增长策略
- private Long id; // 用户的唯一标识
- @Column(nullable = false) // 映射为字段,值不能为空
- private String name;
- @ManyToMany(mappedBy = "authorities")
- private List<User> userList;
- protected Authority() { // JPA 的规范要求无参构造函数;设为 protected 防止直接使用
- }
- @Override
- public String getAuthority() {
- return name;
- }
- }
在启动项目后报错
![](https://oss.liuyanzhao.com/uploads/2018/03/lazy2.png)
然后在 CSDN 上看到这样的解释
然后去网上找资料,就是说因为 hibernate(这里是 Spring Data JPA ) 跟 spring 整合以后,hibernate 的 session 就交给 spring 管理了,请求进来的时候打开 session,请求完成的时候关闭 session。当我们想要使用懒加载去获取数据的时候,这时候原先的那个 session 已经关闭了,不能再获取数据了。由此,spring专门为这种情况作了一个过滤器 org.springframework.orm.hibernate4.support.OpenSessionInViewFilter。它可以把hibernate的session的声明周期维持在视图的开启和关闭之间。这样,只要我们这个视图没有关闭,我们就可以通过 ajax 来使用懒加载获取数据。
在 stackoverflow 找到了解决方案
在 application.properties 里添加如下配置,开启懒加载
- spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏