Mapping сущностей в Hibernate

one-to-manyКак и в JPA, в голом требуется описывать как сущности отображаются на таблицы базы данных. поддерживает три варианта описания отображения: с использованием аннотаций, описание в xml файле, динамическое отображение.

Annotation mapping

Раньше Hibernate использовал собственный набор аннотаций для описания отображения сущностей на таблицы. В последних версиях эти аннотации признали устаревшими и Hibernate использует JPA аннотации для описания отображений сущностей и связей между ними.

Главное различие между JPA и Hibernate в том, что JPA может самостоятельно находить классы сущностей, сканируя аннотации, в то время как Hibernate требует перечисления всех проаннотированных классов в конфигурации:

Кроме того, Hibernate поддерживает дополнительные аннотации для отображения, которые расширяют возможности ORM. Я расскажу о их использовании подробнее позже, в статьях, посвящённых этому дополнительному функционалу.

XML mapping

XML mapping исторически появился в Hibernate первым и долгое время оставлялся единственным механизмом описания отображения сущностей на таблицы. В настоящий момент рекомендуется использовать аннотации, которые активно развиваются и имеют лучший функционал. Но у XML есть и свои плюсы: код сущностей остаётся нетронутым и описание отображения отделено от кода. Соответственно, это единственная возможность применить ORM в том случае, когда код сущностей недоступен или его нельзя изменять.

Традиционно каждая сущность описывается в своём отдельном файле с именем сущность.hbm.xml. Разумеется, имя файла и его расширение могут быть любыми, но желательно придерживаться этого соглашения.

В простом случае сущность описывается перечислением полей и указанием id поля:

В примере выше описывают поля сущности, названия таблицы и столбцов в ней и, кроме того, отношение один-к-одному с сущностью Person. К сожалению в XML mapping нет аналога  @MappedSuperclass, поэтому пришлось включать id поле в каждый класс. Это хороший пример превосходства функционала аннотаций над XML 🙂

Впрочем, XML не так уж и беден. По крайней мере стандартные отношения между классами в нём описываются весьма полноценно. Например один-ко-многим:

Или даже многие-ко-многим:

Или даже всё сразу:

Все файлы отображений так же надо перечислить в конфигурации Hibernate:

Код, который работал с сущностями в примере с аннотациями, работает без изменений с теми же самыми сущностями, но описанными в XML.

Длинный код теста

[свернуть]

Dynamic mapping

Последнее нововведение в Hibernate, это динамическое отображение. И это не отказ от необходимости перечислять сущности в конфигурации, вовсе нет. Это всего лишь возможность не определять конкретные структуры данных со стороны Java, заменяя их на Map. То есть, если есть база данных с таблицей, допустим, persons, можно не определять класс для данных, хранящихся в этой таблице, а загружать её в Map. При этом частичное отображение описывать всё равно нужно.

В первую очередь необходимо описать таблицу и её столбцы:

во вторую очередь, добавить описание таблицы в конфигурацию Hibernate и включить поддержку dynamic mapping:

И теперь можно создавать записи в базе из Map. Обратите внимание, что при сохранении указывается имя сущности из её описания:

Сохранённую сущность можно и прочитать обратно в Map:

Код примера доступен на github.