Отображение в структуру БД иерархии наследования Java в одну таблицу для всех наследников без использования колонки-дискриминатора

Классы сущностей Java могут иметь иерархическую структуру и существует ряд стратегий отображения этой структуры в БД. Одной из стратегий является отображение всех наследников в одну таблицу по имени предка. Подробно сам способ, а также его преимущества и недостатки описаны здесь.

Особенностью единой таблицы для хранения данных всех потомков является наличие колонки-дискриминатора, по которой определяется, какая строка в какой именно класс потомок должна быть отображена.

Если по каким-то причинам нет возможности иметь такую колонку, то можно обойтись без неё. Тогда придётся указать Hibernate’у фрагмент SQL, который он будет добавлять в запрос для того, чтобы различать, на какой класс отображать данные той или иной строки таблицы.

Читать далее

Автоматический подбор версий зависимостей Spring Boot и Spring Framework приложений в сборщиках Maven и Gradle

В старых Spring Framework приложениях часто возникала проблема согласования версий зависимостей. Например, если в проекте используется org.springframework.data:spring-data-jpa той или иной версии, то к этой зависимости нужно подобрать в пару org.hibernate.orm:hibernate-core какой-то подходящей версии.

Spring Boot решил эту проблему не только для собственно Spring Boot приложений, но также и для Spring Framework приложений.

Читать далее

Отображение в структуру БД иерархии наследования Java в одну таблицу для всех наследников.

Классы сущностей Java могут иметь иерархическую структуру и существует ряд стратегий отображения этой структуры в БД. Одной из стратегий является отображение всех наследников в одну таблицу по имени предка.

То есть, если классы Client и Employee наследуют класс Person, то Hibernate создаёт одну таблицу PERSON, в которой хранит данные, отображённые как из объектов класса Client, так и из Employee.

Такая таблица получается не нормализованной и вынуждена допускать то или иной количество nullable полей, что имеет свои недостатки и может быть неприемлемым. Однако у этого похода есть свои преимущества. В одной таблице хранятся данные о различных объектах предметной области, что позволяет делать выборку разных объектов по общим полям. Это, вероятно, самый быстрый способ создавать полиморфные списки объектов типа List<Person>, делая выборку из БД.

Читать далее

Отображение в структуру БД иерархии наследования Java по принципу «отдельная таблица на каждый конкретный класс» с учётом полиморфизма с помощью Hibernate

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

То есть, если классы Client и Employee наследуют класс Person, то Hibernate создаёт для каждого отдельную таблицу, при этом нам становится доступно использование единого репозитория PersonRepository, который будет в одном запросе делать выборку из обеих таблиц (через union) и, как следствие, легко формировать списки типа List<Person>.

Читать далее

Отображение в структуру БД иерархии наследования Java без учёта полиморфизма с помощью Hibernate

Классы сущностей Java могут иметь иерархическую структуру и существует ряд стратегий отображения этой структуры в БД. Самой простой стратегией является отображение каждого конечного конкретного класса в отдельную таблицу с полным игнорированием полиморфных отношений.

То есть если классы Client и Employee наследуют класс Person, то Hibernate создаёт для каждого отдельную таблицу и при этом тот факт, что оба класса наследуют Person для Hibernate не будет иметь значения. Hibernate не будет способен искать объекты типа Person, составлять и возвращать из БД списки типа Person, в которых были бы смешаны данные из двух таблиц. Он будет работать с CLIENT и EMPLOYEE только как с абсолютно не связанными таблицами.

Читать далее

Конвертация типа колонки, создаваемой для поля встраиваемого (@Embeddable) класса в Hibernate.

Классы-значения имеют свой набор полей и при встраивании в класс-сущность каждому такому полю будет создана колонка соответствующего типа, например, VARCHAR для полей типа String, BIGINT для полей типа Long.

Типы создаваемых колонок можно поменять с помощью конвертеров не только для полей класса-сущности, но и для полей встраиваемых классов.

Читать далее

Произвольное преобразование Java типов в типы данных конкретной СУБД с помощью интерфейса javax.persistence.AttributeConverter в Hibernate

Мы привыкли использовать задействованные по умолчанию в Hibernate преобразования Java типов в соответствующие типы нашей СУБД. Так для полей типа java.lang.String создаётся колонка типа VARCHAR, для java.lang.Long — BIGINT (или аналоги специфичные для конкретного вендора).

При этом в Hibernate есть возможность создавать собственные конвертеры, с помощью которых можно преобразовывать данные собственных типов в стандартные Java типы (например, в String), чтобы Hibernate мог их сохранить, а затем и восстановить из колонок соответствующих типов. Например, наш кастомный тип FullName может быть конвертирован в String и сохранён в поле типа VARCHAR.

Читать далее

Переопределение параметров полей встраиваемых @Embeddable классов с помощью аннотаций @Embedded и @AttributeOverride в Hibernate

При создании колонок класса-сущности для сохранения значений классов-значений можно переопределить параметры колонок, описанные в помеченных аннотацией @Embeddable классах-значениях. Можно изменить имена колонок и их всевозможные ограничения.

Допустим класс Person содержит поле Address address. Класс Address помечен @Embeddable и хранит данные своих полей в соответствующих колонках таблицы PERSON. Но сами настройки полей указаны в классе Address. Так вот эти настройки легко переопределяются в классе Person.

Читать далее

Как в PostgreSQL дропнуть все сиквенсы

Прямого способа удалить все сиквенсы из БД как такового нет, но есть один приём, позволяющий сделать это в вполне «автоматическом» режиме без необходимости дропать каждый сиквенс вручную.

Читать далее

Сохранение данных нескольких классов предметной области в одну строку БД с помощью аннотации @Embeddable в Hibernate

В объектно-реляционном отображении различают сущности (entity) и значения (value). Сущности — это данные, имеющие свой жизненный цикл, а с ним и собственную таблицу с id в БД. Значения не имеют собственного жизненного цикла и, как правило, сохраняются в одну строку с сущностью, от которой зависят.

Так, например, адрес может с одной стороны быть представлен отдельным классом в Java, но в БД храниться в виде соответствующих колонок в таблице PERSON. Если адрес у каждого человека один и существует только в привязке к конкретному человеку, то нет никакой необходимости заводить для адресов отдельную таблицу ADDRESS и делать связь один к одному между таблицами PERSON и ADDRESS. Достаточно хранить все данные в PERSON.

Чтобы при этом было возможно в Java-коде пользоваться для адресов отдельным классом, мы можем использовать аннотацию @Embeddable над классом Address.

Читать далее