StackoverflowError: у меня есть цикл, но я не знаю, где и почему

Я знаю, что у меня где-то есть петля, но я не знаю, где и почему. Стараюсь добавлять тренеров на свой курс (Курс). Это мой код:

@EqualsAndHashCode( callSuper = false )
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Kurs extends PanacheEntityBase implements Serializable {

    @Id
    @GeneratedValue( strategy = GenerationType.AUTO )
    private Long id;

    @Basic
    @Column(name = "name", nullable = false)
    private String name;

    @OneToMany(mappedBy = "kurs", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Kurs2Trainer> trainers = new HashSet<>();

    public void addTrainer(Kursuser trainer) {
        // Create a Kurs2Trainer object
        Kurs2Trainer kurs2Trainer = new Kurs2Trainer();
        kurs2Trainer.setTrainer(trainer);
        kurs2Trainer.setKurs(this);

        // Add the Kurs2Trainer object to the trainers set
        this.trainers.add(kurs2Trainer);

        // Add this Kurs to the trainer's set
        trainer.getTrainerBei().add(kurs2Trainer);
    }
}

Курсузер:

@Entity
@Data
@EqualsAndHashCode( callSuper = false )
@NoArgsConstructor
@AllArgsConstructor
public class Kursuser extends PanacheEntityBase implements Serializable {

    @Id
    private Long id;

    @OneToOne( fetch = FetchType.LAZY )
    @MapsId
    private User user;

    /*
    Diese Person ist Trainer an den folgenden Kursen
     */
    @OneToMany( mappedBy = "trainer", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Kurs2Trainer> trainerBei = new HashSet<>();
}

Курс2Тренер:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Kurs2Trainer implements Serializable {

    @EmbeddedId
    private Kurs2TrainerID id = new Kurs2TrainerID();

    @MapsId("trainerId")
    @ManyToOne( fetch = FetchType.LAZY )
    @JoinColumn( name = "trainer_id" )
    private Kursuser trainer;

    @MapsId("kursId")
    @ManyToOne( fetch = FetchType.LAZY )
    @JoinColumn( name = "kurs_id" )
    private Kurs kurs;
}

Kurs2TrainerID:

@Data
@Embeddable
public class Kurs2TrainerID implements Serializable {
    @Column(name = "trainerId")
    private Long trainerId;
    @Column(name = "kursId")
    private Long kursId;
}

Когда я пытаюсь запустить этот код:

private void addTrainerToKurs(User trainer, Kurs k){
    //Check if we have already the trainer in the course
    if ( CollectionUtils.isNotEmpty( k.getTrainers() ) ) {
        for(Kurs2Trainer kTrainer : k.getTrainers()){
            if (kTrainer.getId().getTrainerId().equals( trainer.getId())){
                return;
            }
        }
    }

    //We dont have this user in our course so add
    Kursuser trainerKursuser = kursuserService.getKursuser(trainer);
    k.addTrainer(trainerKursuser);
}

Я получаю следующее сообщение об ошибке:

java.lang.StackOverflowError
    at at.tanzauswertung.portal.kurs.entities.Kursuser.$$_hibernate_read_id(Kursuser.java)
    at at.tanzauswertung.portal.kurs.entities.Kursuser.getId(Kursuser.java:25)
    at at.tanzauswertung.portal.kurs.entities.Kursuser.hashCode(Kursuser.java:19)
    at at.tanzauswertung.portal.kurs.entities.Kurs2Trainer.hashCode(Kurs2Trainer.java:11)
    at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124)

Пожалуйста, покажите мне мою ошибку. Большое спасибо

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У вас двусторонняя связь между Курсом и Курс2Трейнер. И кажется, что их метод hashCode пытается вызвать друг друга, отсюда и цикл.

Вам следует реализовать собственные методы hashCode и Equals для своих классов, чтобы избежать такой рекурсии. Например, можно вместо этого использовать их идентификаторы.

Этот ответ, похоже, применим к вашему случаю, включая некоторые собственные механизмы Hibernate для реализации этого за вас: https://stackoverflow.com/a/65018262/10119664

Другие вопросы по теме