Descripción

El siguiente enfoque para almacenar una jerarquía de clases es almacenar todas las clases de la jerarquía en una sola tabla . Esta estrategia se llama Single Table .

Por ejemplo, así:

CREATE TABLE user_ employee_client {
  id INT,
  name VARCHAR,
  birthday DATE,
  occupation VARCHAR,
  salary INT,
  join DATE,
  address VARCHAR,
  DTYPE VARCHAR
}

Es decir, tenemos una tabla en la que las columnas de todas las clases de nuestra jerarquía están marcadas con diferentes colores. También hay una columna de servicio especial DTYPE VARCHAR , donde Hibernate almacenará el nombre de la clase de Entidad.

Lo único que queda por hacer es explicarle a Hibernate que los datos de las clases de Entidad ahora se almacenan en la base de datos en una tabla. Esto se puede hacer usando la anotación @Inheritance :

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

Un ejemplo de nuestras clases:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Entity
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;
}

Cómo se almacenan los datos

Ahora escribamos un ejemplo donde creamos un par de nuestras entidades y las guardamos en la base de datos:

Employee employee = new Employee();
employee.id = 101;
employee.name = "Ivanov";
employee.birthday = LocalDate.of("01-01-1999");
employee.occupation = "Programmer"
employee.salary = 100000;
employee.join = LocalDate.of("12-01-2018");
session.persist(employee);

Client client = new Client();
client.id = 102;
client.name = "Petrov";
client.birthday = LocalDate.of("15-11-1988");
client.address = "Shandara";
session.persist(client);

Al guardar en la base de datos, se ejecutará la siguiente consulta SQL:

INSERT INTO user_ employee_client (id, name, birthday, occupation, salary, join, DTYPE)
VALUES (101, 'Ivanov', '01-01-1999', 'Programmer', 100000, '12-01-2018', 'Employee')

INSERT INTO user_ employee_client (id, name, birthday, address, DTYPE)
VALUES (102, 'Petrov', '15-11-1988', 'Shandara', 'Client')

Al guardar datos en una tabla, Hibernate pasa solo los campos de entidad que conoce. Esto significa que las columnas no especificadas serán NULL.

Y esto quiere decir que no se puede especificar el tipo NOT NULL para la columna de ocupación, ya que cuando se almacena un cliente en la misma tabla, su ocupación será NULL. Esta es una de las desventajas de almacenar diferentes entidades en la misma tabla.

El último campo de la consulta SQL es la columna DTYPE, que contiene el nombre de la clase Entity. Hibernate lo utiliza cuando desea leer datos de su tabla.

Ejemplo:

List<User> accounts = session.createQuery("from User").list();

Esta consulta devolverá una lista de todos los objetos de tipo usuario almacenados en la base de datos: Usuario, Empleado y Cliente. Según la columna DTYPE, el tipo de entidad se determinará correctamente y se creará un objeto de la clase correcta.

En nuestro caso, habrá dos objetos en la lista de cuentas: un tipo Empleado y un tipo Cliente.

Reglas HQL.