Сопоставление родительских и дочерних отношений - составной ключ, образованный полями двух объектов - PullRequest
1 голос
/ 26 августа 2010

Существует три объекта: GrandParent, Parent и Child

  • GrandParent содержит grandParentId
  • Parent содержит объект GrandParent, parentId, некоторые атрибуты и список Child.
  • Child содержит childId и некоторые атрибуты.

Существует четыре таблицы: GrandParent, Parent, Child, ParentsChildrenList

  • GrandParent, первичный ключ которого - {grandParentId}
  • Родитель, чей первичный ключ - {grandParentId, parentId}
  • Дочерний, чей первичный ключ - {grandParentId, childId}
  • ParentsChildrenList, первичный ключ которого - {grandParentId, parentId, childId}

Родитель и ребенок идентифицируются с помощью составных ключей.

Как должны отображаться эти отношения?Обратите внимание, что объект Child не содержит ссылки на Parent или GrandParant, однако таблица Child использует grandParentId как часть своего первичного ключа.

Эта структура таблиц удовлетворяет сценариям использования.Однако сопоставление не является простым.Любое понимание дизайна приветствуется.

[--- Обновление 1 ---]

Я добавил объект GrandParent к Child и создал составной ключ ChildId для сопоставления с таблицами.
Вопрос остается:Может ли Child позаимствовать часть своего идентификатора у Parent?Таким образом, мне не нужно вводить GrandParent в Child исключительно для постоянства.

[--- Update 2 ---]

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

Ответы [ 2 ]

2 голосов
/ 27 августа 2010

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

Тем не менее, команда, в которой я участвовал, решила эту проблему, создав собственный тип для идентификатора, которому была назначена одна из частей.и был сгенерирован.

Это также может быть полезно http://opensource.atlassian.com/projects/hibernate/browse/HHH-2060

0 голосов
/ 27 августа 2010

Чтобы добавить то, на что ссылался другой пост, создание пользовательского типа обеспечивает гораздо большую гибкость при определении ключей.Вы также можете использовать пользовательский тип идентификатора с одним столбцом, но добавить свою собственную пользовательскую логику для генерации суррогатного ключа на основе параметров в конструкторе.

Составной пример:

      (Child ) 
      public class Child implements java.io.Serializable {
         private ChildId id;
             ....
      (ChildId )
      public class ChildId implements java.io.Serializable {
        private long id;
        private long parent_id;
            .....
     (Child.cfg.xml)
          ....
      <composite-id name="id" class="ChildId">
        <key-property name="id" type="long">
            <column name="id" />
        </key-property>
        <key-property name="parent_id" type="long">
            <column name="parent_id" />
        </key-property>
      </composite-id>
         .....

использование:

   Child c = new Child ();
   ChildId cid = new ChildId(null,1);
   c.setId(cid);
   session.save(c);

Создание настраиваемого типа позволяет выполнять множество настроек, тесно связанных с ORM, против встраивания решения в прикладной уровень.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...