Description
Chacune des stratégies et techniques ci-dessus a ses propres avantages et inconvénients. Les recommandations générales pour choisir une stratégie spécifique ressembleront à ceci :
Stratégie TABLE_PER_CLASS basée sur UNION
Cette stratégie est mieux choisie si les requêtes et les associations polymorphes ne sont pas requises. Si vous faites rarement (ou pas du tout) "select user from User user". Si vous n'avez aucune classe Entity faisant référence à User, c'est la meilleure option (puisque vous pouvez toujours ajouter des requêtes et des associations polymorphes optimisées).
Stratégie SINGLE_TABLE
Cette stratégie doit être utilisée :
a) Uniquement pour des tâches simples. Dans les situations où la normalisation et la contrainte NOT NULL sont critiques, la stratégie #3 (JOINED) doit être préférée. Il est logique de se demander si, dans ce cas, il ne vaut pas la peine d'abandonner complètement l'héritage et de le remplacer par la délégation.
b) Si des requêtes et des associations polymorphes sont requises, ainsi qu'une définition dynamique d'une classe concrète à l'exécution. Dans le même temps, les sous-classes déclarent relativement peu de nouveaux champs, et la principale différence avec une superclasse réside dans le comportement.
Et en plus de cela, vous avez une conversation sérieuse avec le DBA.
Stratégie JOINTE
Cette stratégie est la plus efficace en termes de rapidité et de CONTRAINTES. Il convient dans les cas où des requêtes et des associations polymorphes sont nécessaires, mais les sous-classes déclarent relativement de nouveaux champs.
Une mise en garde ici : la décision entre JOINED et TABLE_PER_CLASS nécessite une évaluation des plans d'exécution des requêtes sur des données réelles, car la largeur et la profondeur de la hiérarchie d'héritage peuvent rendre le coût des jointures (et, par conséquent, les performances) inacceptable.
Séparément, il convient de prendre en compte que les annotations d'héritage ne peuvent pas être appliquées aux interfaces.
EXPLICITE
Il peut également y avoir une situation où vous avez une hiérarchie de classes Entity avec une stratégie de stockage partagé dans la base de données. Mais pour une raison quelconque, vous ne voulez pas qu'une classe hiérarchique soit renvoyée lorsqu'une requête est effectuée sur la classe de base.
Il y a une annotation pour cela :
@Polymorphism(type = PolymorphismType.EXPLICIT)
Si on l'ajoute à la 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;
}
Ensuite, les requêtes HQL ignoreront les objets de cette classe lors de l'interrogation de la classe de base :
List<User> accounts = session.createQuery("from User").getResultList();
Cette requête renverra une liste d' objets User et Employee , mais pas Client .
GO TO FULL VERSION