5.1 Descrição

E, finalmente, a última estratégia é Tabela por classe. Isso significa que uma tabela separada será usada para cada classe. De certa forma, esta é a mesma MappedSuperClass, apenas em um formulário atualizado.

Primeiro, você precisa usar uma anotação:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

Classes com esta anotação ficarão assim:


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

E mesas separadas para cada turma. Por exemplo, estes:


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
}

A principal diferença é que um ID de passagem (PRIMARY KEY) é usado para todas as tabelas. Você não pode ter linhas diferentes com o mesmo id, não apenas dentro da mesma tabela, mas também dentro deste grupo de tabelas. O Hibernate cuidará disso.

5.2 Exemplos

É muito interessante ver como tudo funciona.

Você pode escrever uma consulta HQL simples para obter todos os usuários: User, Employee, Client :

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

Mas o Hibernate, por sua vez, vai gerar uma query bem interessante. Ele fará uma seleção de todas as mesas, depois combinará através do UNION ALL em uma espécie de mesa virtual, e só então irá buscar e/ou selecionar

Mas, para mesclar tabelas com colunas diferentes, elas primeiro precisam ser complementadas com colunas falsas. Por exemplo, a tabela do usuário precisa ser complementada com colunas:

  • occupation VARCHAR
  • salary INT
  • join DATE
  • address VARCHAR

Um exemplo de uma consulta SQL à tabela do usuário antes da execução UNION ALL:


SELECT   id,
         name,
         birthday,
         CAST(NULL AS VARCHAR) AS occupation,
         CAST(NULL AS INT) AS salary,
         CAST(NULL AS DATE) AS join,
         CAST(NULL AS VARCHAR) AS address,
         0 AS clazz
FROM  user

Um exemplo de consulta SQL para a tabela de funcionários antes da execução UNION ALL:


SELECT   id,
         name,
         birthday,
         occupation,
         salary,
         join,
         CAST(NULL AS VARCHAR) AS address,
         1 AS clazz
FROM  employee

Um exemplo de consulta SQL à tabela do cliente antes da execução UNION ALL:


SELECT  id,
        name,
        birthday,
        CAST(NULL AS VARCHAR) AS occupation,
        CAST(NULL AS INT) AS salary,
        CAST(NULL AS DATE) AS join,
        address,
        2 AS clazz
FROM client

A boa notícia é que as consultas HQL funcionarão da maneira que você deseja.

A má notícia é que eles podem ser lentos se houver muitos dados nas tabelas. Porque primeiro você precisa selecionar dados de todas as tabelas, depois combinar suas linhas com UNION ALLe só depois filtrar.