#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. Потому что это приведет к той же проблеме. Это может немного сбить с толку. Я не уверен, что у нас есть какая-либо возможность сделать это или нет. Заранее спасибо.