Hibernate битовый массив для отображения сущности - PullRequest
2 голосов
/ 26 апреля 2010

Я пытаюсь сопоставить нормализованную модель Java с устаревшей схемой базы данных, используя Hibernate 3.5. Одна конкретная таблица кодирует внешние ключи в отношении «один ко многим» в виде столбца битового массива.

Рассмотрим таблицы person и club, которые описывают принадлежность людей к клубам:

person: .----.------.    club: .----.---------.---------------------------.
        | id | name |          | id |   name  | members | binary(members) |
        |----+------|          |----+---------|---------+-----------------|
        |  1 | Bob  |          | 10 | Cricket |       0 |             000 |
        |  2 | Joe  |          | 11 | Tennis  |       5 |             101 | 
        |  3 | Sue  |          | 12 | Cooking |       7 |             111 |   
        '----'------'          | 13 | Golf    |       3 |             100 |
                               '----'---------'---------'-----------------'

Так что, надеюсь, ясно, что person.id используется как битовый индекс в битовом массиве club.members:

.---.---.---.
| S | J | B |
| u | o | o |
| e | e | b |
|---+---+---|
| 1 | 0 | 1 |
'---'---'---'

В этом примере столбец members говорит нам, что:

  • никто не является членом Cricket --- флаги не установлены
  • Боб / Сью -> Теннис --- флаги в позициях 1 и 3 установлены
  • Боб / Сью / Джо -> Готовить --- флаги в позициях 1, 2 и 3 установлены
  • Сью -> Гольф --- флаг в позиции 3 установлен

Теперь, для этого примера, вместо этого можно было бы использовать таблицу соединения, которая упростила бы вопросы и избежала бы многих потенциальных проблем - например: максимальный диапазон members устанавливает верхнюю границу для числа people строк. Тем не менее, я застрял с этой схемой, и, кажется, были факторы в пользу использования столбца битового массива, когда.

В моем домене Java я хотел бы смоделировать эту схему с такими объектами:

class Person {
    private int id;
    private String name;
    ...
}

class Club {
    private Set<Person> members;
    private int id;
    private String name;
    ...
}

Я предполагаю, что должен использовать реализацию UserType, но не смог найти примеров, когда элементы, описываемые пользовательским типом, являются ссылками на сущности, а не на буквальные значения полей или их составные части. Кроме того, я знаю, что мне придется рассмотреть, как person сущности выбираются при загрузке экземпляра club.

Может кто-нибудь сказать мне, как я могу приручить эту устаревшую схему с Hibernate?

Обновление

Недавно мне пришлось вернуться к этому типу отображения в устаревшей базе данных. На этот раз стало очевидно, что наш эквивалент таблицы members на самом деле является статическим набором и может быть жестко закодирован как Enum. С этим упрощением было довольно просто реализовать Hibernate UserType, который преобразуется между битовым массивом и набором перечислений.

1 Ответ

1 голос
/ 27 апреля 2010

Я никогда не сталкивался с такой ситуацией, но я думаю , что вам потребуется реализовать пользовательский UserCollectionType (см. Главу 5.2.3. Типы пользовательских значений в Hibernate Core документация), UserCollectionType является точкой расширения , которая может использоваться для поддержки любой чертовой коллекции и семантики сбора, которая вам нравится .

Я не уверен, насколько хорошо они поддерживаются аннотациями (в соответствии с HHH-4417 , вам, возможно, придется использовать хак). Использование hbm.xml для этого было бы неплохо, ИМО.

Еще несколько указателей / обсуждений:

...