私は簡単なスプリングブートアプリケーションを書いています。なぜSpringブートが "ロールのコレクションを遅延して初期化できませんでした"がEagerフェッチタイプで解決されるのはなぜですか?
認証部分については、カスタムUserDetailsを実装しています。私はManyToMany
注釈にフェッチタイプEager
を作るとき
Authentication Failed: failed to lazily initialize a collection of role: com.boot.cut_costs.config.security.CustomUserDetails.roles, could not initialize proxy - no Session
CustomUserDetails.java
@Entity
@Table(name="ACCOUNT_USER")
public class CustomUserDetails implements UserDetails {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "USER_ID")
private long id;
@NotBlank
@Column(name = "USERNAME")
private String username;
@NotBlank
@Column(name = "PASSWORD")
private String password;
@Column(name = "LOCKED")
private boolean locked;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "USER_ROLE",
joinColumns = @JoinColumn(name = "USER_ID"),
inverseJoinColumns = @JoinColumn(name = "ROLE_ID"))
private Set<CustomRole> roles;
public CustomUserDetails(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<GrantedAuthority> authorities) { // jpa only
this.setUsername(username);
this.setPassword(password);
this.roles = new HashSet<CustomRole>();
for (GrantedAuthority authority: authorities) {
roles.add(new CustomRole(authority.getAuthority()));
}
}
public CustomUserDetails() { // jpa only
}
@Override
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Set<CustomRole> getRoles() {
return roles;
}
public void setRoles(Set<CustomRole> roles) {
this.roles = roles;
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
ArrayList<String> authoritiesList = new ArrayList<String>();
for (CustomRole role: roles) {
authoritiesList.add(role.getRole());
}
return AuthorityUtils.commaSeparatedStringToAuthorityList(String.join(",", authoritiesList));
}
//Some more getters and setters ...
}
CustomRole.java
@Entity
@Table(name="ACCOUNT_ROLE")
public class CustomRole {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="ROLE_ID")
private long id;
@Column(name="ROLE")
private String role;
public long getId() {
return id;
}
//delete if not necessary
public void setId(long id) {
this.id = id;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public CustomRole() {} //for jpa
public CustomRole(String role) {
this.role = role;
}
}
、:私は、ログインエンドポイントに要求を行うとき、私はこの例外を取得しますできます。
これは良いことではありません。まず、理由を知りたいのですが?第二に、私は良い習慣が何かを知りたいですか?サービス層とDAOをここに混ぜていますか?
私はたぶん何か間違っていると言います私はあなたにアクセスしようとする前にトランザクションを終了すると思います怠惰なコレクション、それをロードせずに。 eagerモードは明らかにそれを修正しますが、もっと賢明な方法は、サービスメソッドが同じトランザクションでコレクションをロードして、遅延した動作をして、必要なときにサービスを介してコレクションを引き出すことです。 –