2010-06-21 3 views
6

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

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

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

Производительность улучшилась, так как мы включили кеш второго уровня. Однако мы также начали сталкиваться с ObjectNotFoundExceptions.

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

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

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

Спасибо.

ответ

1

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

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

+0

Хорошего момент. База данных доступна и обновляется кодом Java в нашем приложении. Эта ситуация вряд ли изменится. Поэтому удаление ON DELETE CASCADE не повлияет на другие приложения/скрипты и т. Д. –

+0

Затем перейдите и сделайте это с помощью hibernate – bwawok

+0

Почему бы не оставить базу данных 'ON DELETE CASCADE' в сочетании с hibernate delete cascade? база данных удаляет ее, hibernate пытается удалить каскадированные дочерние элементы, но ничего не удалять. Так что ничего не должно произойти, или я ошибаюсь? – djmj

1

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

@OnDelete(action = OnDeleteAction.CASCADE) 

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

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

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

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

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

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

http://www.mail-archive.com/[email protected]/msg03801.html

+0

Правильно ли работает кеш второго уровня с @OnDelete? Все, что мне удалось найти: no - http://stackoverflow.com/a/21155878/548473. – GKislin

+1

Он работает! Он работает с кешем, без проблем. Но, как всегда: вам нужно понять, что он делает и что ожидает спящий режим – Janning