Hibernate кэш второго уровня и ON DELETE CASCADE в схеме базы данных - PullRequest
6 голосов
/ 21 июня 2010

Наше Java-приложение имеет около 100 классов, сопоставленных с базой данных (SQL Server или MySQL).Мы используем Hibernate в качестве нашего ORM (с файлами отображения XML).

Мы указываем ограничения FOREIGN KEY в нашей схеме базы данных.В большинстве наших FOREIGN KEY ограничений также указывается ON DELETE CASCADE.

. Недавно мы начали включать кэширование Hibernate 2-го уровня (для популярных объектов и коллекций), чтобы уменьшить некоторые проблемы с производительностью.улучшилось, так как мы включили кэш 2-го уровня.Однако мы также начали сталкиваться с ObjectNotFoundExceptions.

Кажется, что ObjectNotFoundExceptions происходят, поскольку база данных удаляет строки таблицы под Hibernate.Например, когда мы удаляем Parent с Hibernate, схема базы данных будет ON DELETE CASCADE для любых Child объектов.Это очевидно происходит без знания Hibernates, поэтому у него нет возможности обновить кэш 2-го уровня (и удалить все удаленные Child сущности).

Мы считаем, что решение этой проблемы заключается в удалении ON DELETE CASCADE из нашей схемы базы данных (но оставьте FOREIGN KEY s).Вместо этого нам нужно настроить Hibernate на удаление Child зависимостей с помощью обычного SQL для удаления, что также заставит Hibernate обновить кэш 2-го уровня.Некоторое ограниченное тестирование показало, что этот подход, похоже, работает.

Я хотел бы получить отзывы сообщества по этому поводу.Есть ли альтернативные (лучшие?) Решения нашей проблемы?Как другие справляются с этой ситуацией?В общем, какие компромиссы следует учитывать при использовании ON DELETE CASCADE в схеме базы данных с Hibernate?

Спасибо.

Ответы [ 2 ]

1 голос
/ 08 марта 2014

Если вы используете ON DELETE CASCADE в своей базе данных, вам нужно указать hibernate, например:

@OnDelete(action = OnDeleteAction.CASCADE)

это отличается от

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)

Последний говорит что-то hibenrateоб отношениях в памяти.Первый оптимизирует удаление операторов SQL на уровне базы данных.Hibernate должен знать, что DB заботится об удалении дочерних элементов.

Посмотрите на этот сайт хорошее объяснение этого механизма:

http://eddii.wordpress.com/2006/11/16/hibernate-on-deletecascade-performance/

икомментарий от разработчика этой функции:

http://www.mail-archive.com/hibernate-devel@lists.sourceforge.net/msg03801.html

1 голос
/ 21 июня 2010

Если вы всегда собираетесь удалять через свою программу, вы хотите снять ограничение с базы данных и указать объекту гибернации ON DELETE CASCADE, чтобы позаботиться о связанных парнях.

С другой стороныЕсли вы собираетесь удалять объекты иногда в своем Java-приложении, а иногда и на уровне базы данных, вы получите странные зависшие данные.В этом случае вам может понадобиться более сложный подход. Вы не знали, так ли это, поэтому не будем вдаваться в подробности.

...