【发布时间】:2019-01-25 08:57:53
【问题描述】:
我会给你看同样的代码然后我会问一个问题。
AccountService.java
@Service
public class AccountService implements IAccountService, StandardizeService<Account>{
@Autowired
private AccountRepository accountRepository;
@Autowired
private AccessRoleRepository accessRoleRepository;
@Autowired
private ActivationCodeRepository activationCodeRepository;
@Autowired
private ActivationCodeService activationCodeService;
@Override
public Account addNew(Account account){
if(!validateAccount(account))
return null;
if(!accountRepository.findByUsernameOrEmail(account.getUsername(), account.getEmail()).isEmpty())
return null;
account.setEnabled(false);
account.setAccessRole(accessRoleRepository.getAccessRoleById(3));
account.setCreationTime(new Timestamp(new Date().getTime()));
account.setPassword(this.hashPassword(account.getPassword()));
Account newAccount = accountRepository.save(account);
if(newAccount == null)
return null;
ActivationCode activationCode = activationCodeService.addNew(newAccount, 1);
if(activationCode == null)
return null;
newAccount.setActivationCodes(activationCodeRepository.getActivationCodeById(activationCode.getId()));
return newAccount;
}
//other methods
ActivationCodeRepository.java
public interface ActivationCodeRepository extends CrudRepository<ActivationCode, Long> {
List<ActivationCode> getActivationCodeById(int id);
}
Account.java
@Entity
@Table(name = "accounts")
@NoArgsConstructor
@Data
@AllArgsConstructor
public class Account {
@Id
@Column(name = "id_account")
@GeneratedValue(strategy = GenerationType.AUTO)
@NotNull
private int id;
@Column(name = "username")
@NotNull
@Length(min = 6, max = 15)
private String username;
@Column(name = "email")
@NotNull
@Length(min = 6, max = 100)
private String email;
@Column(name = "password")
@NotNull
@Length(min = 8, max = 100)
private String password;
@Column(name = "register_no")
@NotNull
private Integer register_no;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "id_access_role")
@OnDelete(action = OnDeleteAction.NO_ACTION)
@NotNull
private AccessRole accessRole;
@Column(name = "enabled")
@NotNull
private boolean enabled;
@Column(name = "firstname")
@NotNull
@Length(min = 2, max = 30)
private String firstname;
@Column(name = "lastname")
@NotNull
@Length(min = 2, max = 30)
private String lastname;
@Column(name = "creation_time", updatable = false)
@NotNull
private Timestamp creationTime;
@OneToMany(mappedBy = "account")
private List<ActivationCode> activationCodes;
@OneToMany(mappedBy = "account")
private List<GroupMember> groupMembers;
}
AccessRole.java
@Table(name = "access_roles")
@Entity
@NoArgsConstructor
@Data
@AllArgsConstructor
public class AccessRole {
@Id
@Column(name = "id_access_role")
@GeneratedValue(strategy = GenerationType.AUTO)
@NotNull
private int id;
@Column(name = "role")
@NotNull
private String role;
@JsonIgnore
@OneToMany(mappedBy = "accessRole")
private List<Account> accounts;
@JsonIgnore
@OneToMany(mappedBy = "accessRole")
private List<GroupMember> groupMembers;
}
ActivationCode.java
@Table(name = "activation_codes")
@Entity
@NoArgsConstructor
@Data
@AllArgsConstructor
public class ActivationCode {
@Id
@Column(name = "id_activation_code")
@GeneratedValue(strategy = GenerationType.AUTO)
@NotNull
private int id;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "id_account")
@OnDelete(action = OnDeleteAction.CASCADE)
@NotNull
private Account account;
@Column(name = "type")
@NotNull
private int type;
//1 - for activation account (enabled -> true)
@Column(name = "code")
@NotNull
private String code;
}
我尝试过使用 AccountService 中的 addNew 方法。新帐户已添加,但我遇到了问题:
newAccount.setActivationCodes(activationCodeRepository.getActivationCodeById(activationCode.getId()));
控制台显示错误:
org.hibernate.LazyInitializationException: 延迟初始化失败 角色集合:com.goode.business.AccessRole.accounts,可以 不初始化代理 - 没有会话
这个错误并不完全将我引导到我在上面向你展示的那一行,但这一行没有执行。
错误是关于获取 Lazy (AccessRole.accounts)。我尝试将其更改为:
AccessRole.java
@JsonIgnore
@OneToMany(fetch = FetchType.EAGER, mappedBy = "accessRole")
private List<Account> accounts;
但现在控制台显示循环错误:
org.springframework.web.util.NestedServletException:处理程序调度 失败的;嵌套异常是 java.lang.StackOverflowError
原因:
在 com.goode.business.AccessRole.toString(AccessRole.java:21) 在 java.base/java.lang.String.valueOf(String.java:2788) 在 java.base/java.lang.StringBuilder.append(StringBuilder.java:135) 在 com.goode.business.Account.toString(Account.java:26) 在 java.base/java.lang.String.valueOf(String.java:2788)
您能给我一些建议,我该如何修复它?
【问题讨论】:
-
查看
toString的AccessRole和Account方法——怀疑是那些导致StackOverflowError的方法。 -
是的,它是:com.goode.business.AccessRole.toString(AccessRole.java:21) at java.base/java.lang.String.valueOf(String.java:2788) at java.base/java.lang.StringBuilder.append(StringBuilder.java:135) 在 com.goode.business.Account.toString(Account.java:26) 在 java.base/java.lang.String.valueOf(String. java:2788)
-
您需要从
AccessRole的toString中删除accounts或从Account的toString中删除accessRole之一。这将帮助您解决堆栈溢出问题。
标签: java hibernate spring-data-jpa