Descrição

Cada uma das estratégias e técnicas acima tem suas próprias vantagens e desvantagens. As recomendações gerais para escolher uma estratégia específica serão assim:

Estratégia TABLE_PER_CLASS baseada em UNION

Essa estratégia é melhor escolhida se consultas e associações polimórficas não forem necessárias. Se você raramente faz (ou não faz) "selecionar usuário de Usuário usuário". Se você não tiver nenhuma classe Entity que se refira ao User, esta é a melhor opção (já que você ainda pode adicionar consultas e associações polimórficas otimizadas).

estratégia SINGLE_TABLE

Esta estratégia deve ser usada:

a) Apenas para tarefas simples. Em situações em que a normalização e a restrição NOT NULL são críticas, a estratégia nº 3 (JOINED) deve ser preferida. Faz sentido pensar se neste caso não vale a pena abandonar completamente a herança e substituí-la por delegação.

b) Se forem necessárias consultas e associações polimórficas, bem como definição dinâmica de uma classe concreta em tempo de execução. Ao mesmo tempo, as subclasses declaram relativamente poucos novos campos, e a principal diferença com uma superclasse está no comportamento.

E ainda por cima, você tem uma conversa séria com o DBA.

Estratégia JUNTA

Esta estratégia é a mais eficiente em termos de velocidade e RESTRIÇÕES. É adequado nos casos em que são necessárias consultas e associações polimórficas, mas as subclasses declaram relativamente muitos novos campos.

Uma palavra de cautela aqui: a decisão entre JOINED e TABLE_PER_CLASS requer avaliação dos planos de execução da consulta em dados reais, pois a largura e a profundidade da hierarquia de herança podem tornar o custo das junções (e, como resultado, o desempenho) inaceitável.

Separadamente, vale a pena levar em consideração que as anotações de herança não podem ser aplicadas às interfaces.

EXPLÍCITO

Também pode haver uma situação em que você tenha uma hierarquia de classes Entity com uma estratégia de armazenamento compartilhado no banco de dados. Mas, por qualquer motivo, você não deseja que alguma classe de hierarquia seja retornada quando uma consulta é feita na classe base.

Existe uma anotação para isso:

@Polymorphism(type = PolymorphismType.EXPLICIT)

Se o adicionarmos à classe Client :

@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
@Polymorphism(type = PolymorphismType.EXPLICIT)
class Client extends User {
   String address;
}

Em seguida, as consultas HQL irão ignorar os objetos desta classe ao consultar a classe base:

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

Esta consulta retornará uma lista de objetos Usuário e Funcionário , mas não Cliente .