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 ALL
e só depois filtrar.