Двунаправленное отображение в режиме гибернации не работает

#java #hibernate #hibernate-mapping

#java #переход в режим гибернации #отображение в режиме гибернации

Вопрос:

У меня есть 2 объекта для двух таблиц. Студент имеет отношение один ко многим с ежемесячным посещением. student_id — это столбец соединения. Пожалуйста, посмотрите на приведенный ниже код.

 @Entity
@Table(name="student")
public class Student implements Serializable {

    @Id
    @Column(name="student_id")
    @GeneratedValue(strategy= GenerationType.AUTO)
    private String studentId;
/*
*More codes
*/

    @OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
    private Set<MonthAttendance> monthAttendances;
/*
*mutators
*getter and setter methods
*/

}


@Entity
@Table(name="month_attendance")
public class MonthAttendance implements Serializable {

    @Id
    @Column(name="month_year_id")
    @GeneratedValue(strategy= GenerationType.AUTO)
    private String monthYearId;
/*
*More codes
*/
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "student_id")
    private Student student;
/*
*mutators
*getter and setter methods
*/
}
 

У меня есть класс DAO для получения данных учащихся из базы данных. Я использовал приведенный ниже код для извлечения данных,

 List<Student> studentList = session.createQuery("from Student").list();
List<Student> studentList = session.createQuery("from MonthAttendance").list();
 

Оба работают нормально. Но объект имеет рекурсивную структуру, например, Student имеет MonthAttendance, MonthAttendance имеет Student, снова Student имеет MonthAttendance и продолжается.
есть ли какой-либо способ решить эту проблему? Мне просто нужно, чтобы у студента был месячный доступ, у которого нет student, если я попытаюсь получить Student. Заранее спасибо.

Ответ №1:

Чтобы избавиться от этого рекурсивного поведения, просто удалите:

 cascade = CascadeType.ALL
 

из объекта Student, например:

 @OneToMany(mappedBy = "student")
private Set<MonthAttendance> monthAttendances;
 

Каскад в основном говорит об этом:

Если я выполняю действие над объектом, как я должен действовать в отношении связанного объекта.

Должен ли я выполнить это же действие над ним?

Давайте возьмем ваш пример:

Если я попытаюсь сохранить / сохранить MonthAttendance объект, Hibernate также попытается выполнить операцию сохранения / сохранения Student для связанного с ним объекта. Почему?

Потому что для MonthAttendance объекта в Student ассоциации у нас есть CascadeType.ALL (в разделе CascadeType.ВСЕГО у нас есть 4-5 действий), что означает, что всякий раз, когда вы пытаетесь сохранить / сохранить MonthAttendance , Hibernate пытается выполнить то же действие (сохранить / сохранить в нашем случае) для прикрепленного Student объекта.

Это объясняет, почему вы получаете это рекурсивное поведение, потому что вы отметили обе стороны ассоциации с:

 cascade = CascadeType.ALL
 

Когда вы сохраняете первый объект, он пытается сохранить второй, а второй пытается снова сохранить первый и так далее.

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

1. Спасибо за ответ. Удален «cascade = CascadeType.ALL» из объекта student. Но все еще сталкивается с той же проблемой

2. Можете ли вы опубликовать свою трассировку стека с исключением?

3. Я не получаю никаких исключений. У студента есть набор MonthAttendance, у MonthAttendance есть объекты Student при извлечении данных. Итак, я получаю приведенное ниже исключение при преобразовании моего результата в json,

4. java.lang. Ошибка StackOverflowError в org.codehaus. jackson.impl.WriterBasedGenerator. _writeString(неизвестный источник) в org.codehaus. jackson.impl.WriterBasedGenerator. _writeFieldName(неизвестный источник) в org.codehaus. jackson.impl.JsonGeneratorBase.writeFieldName(неизвестный источник) в org.codehaus. jackson.map.ser.BeanPropertyWriter$StdMethod.serializeAsField(BeanPropertyWriter.java:214) в org.codehaus. jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:58)

5. Поэтому я просто хочу, чтобы объект Student имел набор MonthAttendence, но у MonthAttendance никогда не будет объекта Student, поскольку мы получаем однонаправленное отображение. Я не уверен, возможно ли это или нет. Итак, почему я использовал двунаправленное отображение вместо однонаправленного отображения, заключается в том, что иногда мне может потребоваться получить MonthAttendance вместе с Student, в этом случае у student не должно быть установленного MonthAttendance. Потому что это приведет к той же проблеме. Это может немного сбить с толку. Я не уверен, что у нас есть какая-либо возможность сделать это или нет. Заранее спасибо.