В качестве нового требования я должен сохранить контрольные суммы записей в базе данных.
У нас есть отдельная таблица для контрольных сумм, которая содержит table_name, record_id, record_version, контрольную сумму и некоторые другие поля.У нас также есть базовый класс сущностей, который сохраняет и считывает данные контрольной суммы, используя методы @PostPersist
, @PostUpdate
и @PostLoad
.
Давайте предположим следующий базовый пример:
У нас есть Teacher
a Course
и TeacherCourse
сущности.У сущности Teacher
есть метод addCourse
:
public void addCourse(Long courseId) {
JpaTeacherCourse tc = new JpaTeacherCourse();
JpaCourse course = new JpaCourse();
course.setId(courseId);
tc.setCourse(course);
tc.setTeacher(this);
tc.setStartDate(new Date());
courses.add(tc);
}
В BaseEntity
в методе @PostLoad
мы загружаем последние данные контрольной суммы, используя запрос:
@Query(value = "SELECT * FROM checksums c WHERE c.table_name = :tableName AND c.record_id = :recordId ORDER BY id DESC LIMIT 1", nativeQuery = true)
Проблема в том, что при сохранении объекта Teacher
Hibernate загружает соответствующий курс, и это вызывает метод @PostLoad
.Выбор в @PostLoad
вызывает Hibernate для сброса данных, и окончательный результат - исключение Flush during cascade is dangerous
.
Я полагаю, это потому, что Hibernate не имеет ссылки на сущность курса.Если я изменю свой метод addCourse
следующим образом:
public void addCourse(Long courseId) {
JpaTeacherCourse tc = new JpaTeacherCourse();
CourseRepository repo = BeanUtil.getBean(CourseRepository.class);
Optional<JpaCourse> courseOpt = repo.findById(courseId);
JpaCourse course = courseOpt.get();
tc.setCourse(course);
tc.setTeacher(this);
tc.setStartDate(new Date());
courses.add(tc);
}
В этом случае выбор не запускается во время метода сохранения, и объект сохранения работает нормально.
Моя проблема с этим решениемчто сущность зависит от хранилища, которое кажется неоптимальным решением.
Другой вариант может быть, если метод addCourse
имеет сущность в качестве параметра, но он требует много изменений кода в других местах, и этоТакже возможно добавить объект без реальной ссылки Hibernate в качестве параметра, и это опять-таки исходная проблема.
Поэтому мой вопрос заключается в том, как правильно решить эту проблему?
Проект основан на Spring Boot2.1 и использование Hibernate 5.3