Глава 12. Объектно-реляционные типовые решения... 261
альбому). В этом случае вам не придется определять, какие композиции были удалены из
альбома, поскольку значения их внешних ключей будут обновлены при обновлении аль-
бомов, в которые эти композиции были перемещены.
Обратная ссылка может быть неизменяемой (т.е. композиция не может быть переме-
щена в другой альбом). В этом случае добавление композиции в альбом всегда означает
вставку строки в базу данных, а удаление из альбома — удаление соответствующей строки
из базы данных. Это еще более упрощает обновление коллекций.
Работая с базой данных, необходимо следить за наличием циклических ссылок.
Предположим, нужно загрузить заказ, ссылающийся на покупателя (который тоже будет
загружен). Каждому покупателю соответствует множество платежей (сведения о котором
тоже будут загружены), а каждый платеж ссылается на оплачиваемые им заказы. Послед-
нее множество может включать в себя упомянутый заказ. Таким образом, будет загружен
и этот заказ, после чего все повторяется снова и снова.
Во избежание подобной мешанины можно воспользоваться одним из двух способов
создания объектов. Многие предпочитают применять конструкторы с аргументами, что-
бы создаваемые объекты были полностью загружены данными. В этом случае придется
прибегнуть к загрузке по требованию (Lazy Load, 220), чтобы цикл загрузки прерывался в
нужных местах. Если этого не сделать, вам грозит переполнение стека. Впрочем, если ре-
зультаты тестирования оказались вполне приличными, без применения загрузки по тре-
бованию можно обойтись.
Второй возможный вариант — создать пустой объект и сразу же поместить его в кол-
лекцию объектов (Identity Map, 216). В этом случае при повторной ссылке на объект кол-
лекция объектов сообщит, что он уже был загружен, и цикл будет прерван. Разумеется,
объекты, создаваемые подобным образом, не заполнены данными, однако по окончании
загрузки они будут содержать в себе все, что нужно. Это позволяет избежать описания ча-
стных случаев загрузки по требованию, что было бы крайне утомительно, если нужно
всего лишь корректно загрузить объект.
Назначение
Отображение внешних ключей может применяться для моделирования практически
всех видов связей между классами. Наиболее распространенный случай, когда отображе-
ние внешних ключей применить нельзя, — это связи типа "многие ко многим". Внешние
ключи являются одномерными значениями, а из определения первой нормальной фор-
мы следует, что в одном поле нельзя хранить множественные значения внешних ключей.
В этом случае вместо отображения внешних ключей необходимо воспользоваться отобра-
жением с помощью таблицы ассоциаций (Association Table Mapping, 269).
Если у вас есть поле коллекции без обратного указателя, подумайте о том, не сделать
ли "множественную сторону" ссылки отображением зависимых объектов. Это значитель-
но упростит обработку коллекции.
Если связанный объект является объектом-значением (Value Object, 500), вместо ото-
бражения внешних ключей следует воспользоваться внедренным значением (Embedded
Value, 288).