Наследование InheritanceType.TABLE_PER_CLASS

В этой статье рассмотрим стратегию наследования InheritanceType.TABLE_PER_CLASS. При такой стратегии классы преобразуются в независимые таблицы.

Классы

Родительский класс Customer:

@Data
@NoArgsConstructor
@Entity
@Inheritance(
        strategy = InheritanceType.TABLE_PER_CLASS
)
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;
    private String name;

    public Customer(String name){
        this.name =name;
    }
}

Дочерние классы EmployeeCustomer и ExternalCustomer:

@Entity
@Data
public class EmployeeCustomer extends Customer {
    private int monthsInCompany;
}

@Data
@Entity
public class ExternalCustomer extends Customer {
   private long sum;
}

Таблицы

Генерируются такие независимые таблицы (внешних ключей нет, только первичные):

Table "customer" {
  "id" bigint [pk, not null]
  "name" "character varying(255)"
}

Table "employee_customer" {
  "id" bigint [pk, not null]
  "name" "character varying(255)"
  "months_in_company" integer [not null]
}

Table "external_customer" {
  "id" bigint [pk, not null]
  "name" "character varying(255)"
  "sum" bigint [not null]
}

Select из родительской сущности

Выборка генерирует сложный  SQL.

TypedQuery<Customer> customers=em
               .createQuery("select c from Customer c", Customer.class);

Вышеприведенный JPQL преобразуется в SQL:

SELECT customer0_.id AS id1_0_,
       customer0_.name AS name2_0_,
       customer0_.months_in_company AS months_i1_1_,
       customer0_.sum AS sum1_2_,
       customer0_.clazz_ AS clazz_
FROM
  (SELECT id,
          name,
          NULL::int4 AS months_in_company,
          NULL::int8 AS SUM,
          0 AS clazz_
   FROM customer
   UNION ALL SELECT id,
                    name,
                    months_in_company,
                    NULL::int8 AS SUM,
                    1 AS clazz_
   FROM employee_customer
   UNION ALL SELECT id,
                    name,
                    NULL::int4 AS months_in_company,
                    SUM,
                    2 AS clazz_
   FROM external_customer) customer0_

Итоги

Сохранять можно все сущности (родительские и дочерние) — они пойдут в независимые таблицы.

Заметим, что при стратегии наследования  InheritanceType.TABLE_PER_CLASS нельзя использовать такую стратегию генерации идентификатора:

@GeneratedValue(strategy = GenerationType.IDENTITY)

(Такая стратегия задает автоинкрементное поле). У нас использована @GeneratedValue(strategy = GenerationType.SEQUENCE) — ее можно.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *