Проблемы сохранения

Сегодня у нас будет новая и суперинтересная схема — использование возможностей Hibernate для сохранения в базу иерархии классов.

Иерархия классов — это несколько классов, связанных друг с другом отношением наследования.

Представь, что у тебя есть три класса, которые ты хочешь хранить в базе:


class User {
  int id;
  String name;
  LocalDate birthday;
}

class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}

class Client extends User {
   String address;
}

Классы унаследованы друг от друга. А самое интересное в том, что ты хочешь использовать Hibernate для того, чтобы хранить объекты этих классов в базе данных.

Виды решений

В Hibernate существует 4 возможных способа, которыми он может связать иерархию классов с таблицами в базе данных:

  • MappedSuperclass
  • Single Table
  • Joined Table
  • Table per class

Каждая стратегия предполагает свою собственную структуру таблиц в базе данных. Иногда они довольно сложные. Зато запросы на HQL к ним очень простые. Это как раз тот случай, где ярко проявляются преимущества Hibernate.

Никогда не слышал, чтобы эти термины переводили на русский, так что тоже рекомендую произносить их на английском.

Ниже мы разберем, что означает каждый их них.

@MappedSuperClass

Начнем с самого простого решения — в базе данных у тебя отдельные таблицы для каждого класса. Например, такие:


CREATE TABLE user {
  id INT,
  name VARCHAR,
  birthday DATE
}

CREATE TABLE employee {
  id INT,
  name VARCHAR,
  birthday DATE,
  occupation VARCHAR,
  salary INT,
  join DATE
}

CREATE TABLE client {
  id INT,
  name VARCHAR,
  birthday DATE,
  address VARCHAR
}

О том, что классы для этих таблиц связаны в иерархию, знаешь только ты. Если ты хочешь, чтобы еще и Hibernate об этом знал, тебе нужно добавить родительскому классу аннотацию @MappedSuperclass. Без нее Hibernate просто проигнорирует поля и аннотации родительского класса.

Классы с этой аннотацией будут выглядеть так:


@MappedSuperclass
class User {
  int id;
  String name;
  LocalDate birthday;
}

@Entity
class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}

@Entity
class Client extends User {
   String address;
}

Это самый примитивный способ связывания иерархии классов и базы данных. Такой подход фактически позволяет тебе только избежать дубликата полей в классах.

Запросы к базе данных на HQL будут возвращать только ту сущность, тип которой указан явно. Ты не можешь написать запрос к базе на HQL и получить список всех пользователей: User, Employee, Client.

undefined
1
Задача
Модуль 4. Работа с БД, 15 уровень, 0 лекция
Недоступна
Стратегия MappedSuperClass
Посмотри на скрипт по созданию таблиц. Создай классы-сущности для этих таблиц. Обрати внимание на поля, которые повторяются. Для избежания дублирования используй наследование. Расставь правильно аннотации созданным классам. Не забудь про поле Long id в каждом классе-сущности.