我正在使用Spring Boot应用程序,并且有几个端点返回错误
$ curl -X PUT http://localhost:8080/api/v1/users/calculateReward?userId=1 |jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0parse error: Exceeds depth limit for parsing at line 1, column 6472
100 81714 0 81714 0 0 1641k 0 --:--:-- --:--:-- --:--:-- 1662k
curl: (23) Failed writing body (0 != 7978)
我也收到类似parse error: Invalid numeric literal at line 1, column 9
的错误。
我认为这与管道分隔符有关,但是我以前使用它没有问题。
当我调试时,我得到这样的东西
Method threw 'java.lang.StackOverflowError' exception. Cannot evaluate com.user.reward.models.RewardList.toString()
提供了我模型的类,
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
@NotNull
@NotEmpty
private String name;
@Column(name = "countryName")
@NotNull
@NotEmpty
private String countryName;
/*
* total steps is for the keepign the history of the user movement
* */
@Column(name = "totalSteps")
@Min(value = 0L, message = "The value must be positive")
private int totalSteps;
/*
* current steps is for providing the user reward. We will need to set
* it to zero after processing the user payment
* */
@Column(name = "currentSteps")
@Min(value = 0L, message = "The value must be positive")
private int currentSteps;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<RewardList> rewardLists = new ArrayList<>();
public User() {
}
public User(@NotNull @NotEmpty String name, @NotNull @NotEmpty String countryName) {
this.name = name;
this.countryName = countryName;
}
public User(@NotNull @NotEmpty String name, @NotNull @NotEmpty String countryName, @Min(value = 0L, message = "The value must be positive") int totalSteps) {
this.name = name;
this.countryName = countryName;
this.totalSteps = totalSteps;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public int getTotalSteps() {
return totalSteps;
}
public void setTotalSteps(int totalSteps) {
this.totalSteps = totalSteps;
}
public int getCurrentSteps() {
return currentSteps;
}
public void setCurrentSteps(int currentSteps) {
this.currentSteps = currentSteps;
}
public List<RewardList> getRewardLists() {
return rewardLists;
}
public void setRewardLists(RewardList rl) {
this.rewardLists.add(rl);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return getTotalSteps() == user.getTotalSteps() &&
getCurrentSteps() == user.getCurrentSteps() &&
getId().equals(user.getId()) &&
getName().equals(user.getName()) &&
getCountryName().equals(user.getCountryName()) &&
getRewardLists().equals(user.getRewardLists());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getName(), getCountryName(), getTotalSteps(), getCurrentSteps(), getRewardLists());
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", countryName='" + countryName + '\'' +
", totalSteps=" + totalSteps +
", currentSteps=" + currentSteps +
", rewardLists=" + rewardLists +
'}';
}
}
@Entity
public class RewardList {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "reward")
@Min(value = 0L, message = "The value must be positive")
private double reward;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
public RewardList() {
}
public RewardList(User user) {
this.user = user;
}
public RewardList(@Min(value = 0L, message = "The value must be positive") double reward) {
this.reward = reward;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public double getReward() {
return reward;
}
public void setReward(double reward) {
this.reward = reward;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof RewardList)) return false;
RewardList list = (RewardList) o;
return Double.compare(list.getReward(), getReward()) == 0 &&
getId().equals(list.getId()) &&
getUser().equals(list.getUser());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getReward(), getUser());
}
@Override
public String toString() {
return "RewardList{" +
"id=" + id +
", reward=" + reward +
", user=" + user +
'}';
}
}
我在OS X终端中,该问题的解决方案是什么?
答案 0 :(得分:1)
使用RewardList
显示实体时,User
和toString()
实体之间存在循环依赖关系。用户A将显示奖励B,该奖励B将显示用户A,该奖励B将显示奖励B ...等等,直到您从递归StackOverflowError
中获得toString()
。
您可以通过以下任一方法解决它:
rewardLists
中显示User.toString()
关系数据user
中显示RewardList.toString()
关系数据我会选择选项1,因为User
是该关系的拥有实体。