Аннотация @MappedSuperclass позволяет вынести общие поля в родительский класс, но при этом не создавать для него отдельную таблицу. При такой стратегии классы-наследники преобразуются в независимые таблицы. @MappedSuperclass никак не влияет на структуру в базе — это просто способ вынести общие поля.
Ниже рассмотрим пример.
Классы
Родительский класс Customer:
@Data @NoArgsConstructor @MappedSuperclass public class Customer { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; private String name; public Customer(String name){ this.name =name; } }
Customer — не сущность, в него просто вынесены общие поля сущностей EmployeeCustomer и ExternalCustomer. Класс Customer можно сделать абстрактным. Ассоциаций (@ManyToOne, @OneToMany и т.д.) с ним сделать нельзя. Этот класс можно было бы назвать AbstractEntity.
Дочерние классы EmployeeCustomer и ExternalCustomer:
@Entity @Data public class EmployeeCustomer extends Customer { private int monthsInCompany; } @Data @Entity public class ExternalCustomer extends Customer { private long sum; }
Таблицы
Генерируются две независимые таблицы (внешних ключей нет, только первичные):
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] }
Они включают поля родительского класса и свои.
Итоги
Сохранять можно только дочерние сущности — они пойдут в независимые таблицы и будут включать поля родительской. Отдельно Customer не сохранить, это абстракция, в которую вынесена часть полей.
Поля также можно было бы вынести вовне с помощью @Embedded, но не все (кроме @Id). Здесь же мы вынесли и @Id.
Код примера есть на GitHub.