Hibernate кэш второго уровня и на удалении каскада в схеме базы данных
-
28-09-2019 - |
Вопрос
Наше приложение Java имеет около 100 классов, отображаемых в базе данных (SQL Server или MySQL). Мы используем Hibernate в качестве нашей ORM (с файлами отображения XML).
Мы указываем FOREIGN KEY
Ограничения в нашей схеме базы данных. Большую часть нашего FOREIGN KEY
Ограничения также указывают ON DELETE CASCADE
.
Недавно мы начали включить Hibernate 2-й уровень кэширования уровня (для популярных объектов и коллекций) для смягчения некоторых проблем с производительностью.
Производительность улучшилась, так как мы включили 2-й уровень кэш. Однако мы также начали столкнуться с ObjectNotfoundExceptions.
Кажется, ObjectNotFoundExceptions возникает, потому что база данных удаляет строки таблицы под Зимующий Например, когда мы удаляем Parent
С помощью Hibernate схема базы данных будет ON DELETE CASCADE
любому Child
объекты. Это, очевидно, происходит без зимущих знаний, поэтому он не получит шанс обновить 2-й уровень кэш (и удалить любой удаленный Child
объекты).
Мы считаем, что решение этой проблемы состоит в том, чтобы удалить ON DELETE CASCADE
из нашей схемы базы данных (но сохранить FOREIGN KEY
s). Вместо этого нам нужно настроить Hibernate для удаления Child
Зависимости с нормальным удалением SQL, которые также сделают Hibernate обновлять 2-й кэш уровня. Некоторые ограниченные тестирования показали, что этот подход работает.
Я хотел получить отзывы сообщества на это. Есть ли альтернативные (лучше?) Решения нашей проблемы? Как другие обрабатывают эту ситуацию? В целом, какие компромиссы, которые следует учитывать при использовании ON DELETE CASCADE
В схеме базы данных с гибернатом?
Спасибо.
Решение
Если вы всегда собираетесь удалить через свою программу, вы хотите взять ограничение от базы данных и сообщить об объекте Hibernate на удаление Cascade, чтобы позаботиться о связанных ребятах.
С другой стороны, если вы собираетесь удалить объекты иногда в вашем приложении Java, а иногда и на уровне базы данных, вы получите странные висячие данные. В этом случае вам может потребоваться посмотреть более сложный подход .. Вы не были понятны, если бы это было так, поэтому не собирается пойти в более подробную информацию здесь.
Другие советы
Если вы используете ON DELETE CASCADE
В вашей базе данных вы должны сказать в гибернации, как это:
@OnDelete(action = OnDeleteAction.CASCADE)
Это отличается от
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
Последнее говорит хитрые что-то о отношениях в памяти. Первый оптимизирует удаление операторов SQL на уровне базы данных. Hibernate нужно знать, что БД заботится о удалении детей.
Посмотрите на этот сайт для хорошего объяснения этого механизма:
http://eddii.wordpress.com/2006/11/16/ibernate-on-deleteCascade-performance/
И комментарий от разработчика этой функции:
http://www.mail-archive.com/hibernate-devel@lists.sourceforge.net/msg03801.html.