Java-приложение возвращает завиток: (23) Не удалось записать тело (0! = 8042)

#java #rest #curl #terminal

#java #rest #curl #терминал

Вопрос:

Я работаю с приложением 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() amp;amp;
                getCurrentSteps() == user.getCurrentSteps() amp;amp;
                getId().equals(user.getId()) amp;amp;
                getName().equals(user.getName()) amp;amp;
                getCountryName().equals(user.getCountryName()) amp;amp;
                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 amp;amp;
                getId().equals(list.getId()) amp;amp;
                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, каково решение проблемы?

Комментарии:

1. вы должны следить за этим в коде. Вы можете очистить ввод, например, с помощью выражения регулярного выражения. Но было бы неплохо увидеть ваш код.

2. Вы обращались к данным JSON jq , на которые жалуются? Является ли оно невероятно раздутым и недействительным в качестве jq состояний? Если да, можно ли это исправить в приложении Spring boot?

3. Я обновил вопрос с java.lang.StackOverflowError ошибкой

Ответ №1:

У вас есть циклическая зависимость между RewardList User объектами и при их отображении toString() . Пользователь A отобразит награду B, которая отобразит пользователя A, который отобразит награду B … и так далее, пока вы не перейдете StackOverflowError от рекурсивного toString() .

Вы можете решить это с помощью:

  1. не отображаются rewardLists данные связи в User.toString()
  2. не отображаются user данные связи в RewardList.toString()

Я бы выбрал вариант 1, поскольку User это объект-владелец для этого отношения.

Комментарии:

1. Ошибка исчезает, но я все еще получаю доступ к терминалу parse error: Exceeds depth limit for parsing at line 1, column 6472 curl: (23) Failed writing body (0 != 8026)

2. И он печатает User{id=1, name='Robert', countryName='Germany', totalSteps=200, currentSteps=0}