PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Héritage PostgreSQL avec JPA, Hibernate

Le concept d'héritage de JPA est basé sur des tables ordinaires. Il ne "comprend" pas vraiment l'idée de l'héritage de table de PostgreSQL. C'est l'un des coûts de l'utilisation d'une spécification conçue pour exposer le plus petit dénominateur commun des fonctionnalités et le faire de manière portable.

Consultez ce guide pour un résumé décent des stratégies d'héritage JPA. Notez que dans le nouveau Java 6 JavaDoc pour @Inheritance, il y a une note disant que :

Si l'annotation d'héritage n'est pas spécifiée ou si aucun type d'héritage n'est spécifié pour une hiérarchie de classes d'entités, la stratégie de mappage SINGLE_TABLE est utilisée.

... et si vous regardez comment SINGLE_TABLE fonctionne, il n'est pas surprenant que cela ne fonctionne pas pour vous ; il s'attend à ce que toutes les sous-classes soient dans une grande table avec une valeur de discriminateur magique.

InheritanceType.TABLE_PER_CLASS est plus proche de la façon dont Pg se comporte, mais je soupçonne que l'implémentation JPA sera un peu confuse lorsque les tables de type de base ont des entrées pour chaque entité d'un type feuille. Il essaie de faire des choses comme UNION requêtes sur les tables de sous-classe lors de la requête sur la superclasse, et cela pourrait produire des résultats étranges - au moins une duplication si UNION est utilisé et des problèmes de performances s'il utilise UNION ALL . Selon la manière exacte dont le fournisseur met en œuvre la stratégie, cela peut fonctionner au moins partiellement. Vous auriez à tester, et les résultats seraient peut-être assez spécifiques au fournisseur.

Une très bonne implémentation de la prise en charge de l'héritage PG pour JPA nécessiterait probablement des extensions de fournisseur JPA pour une nouvelle stratégie d'héritage comprenant les extensions PostgreSQL pour l'héritage et pour ONLY requêtes.

Si vous pouvez convaincre votre implémentation JPA d'utiliser SELECT ... FROM ONLY subclass_table quand dans InheritanceType.TABLE_PER_CLASS mode alors il devrait interagir correctement avec l'héritage PostgreSQL. Il ne verrait que les lignes non héritées de chaque table et travaillerait avec elles comme s'il s'agissait de tables ordinaires. Votre autre code non JPA pourrait alors continuer à utiliser les fonctionnalités d'héritage. Je suppose qu'il est possible que vous puissiez modifier le code du dialecte PostgreSQL pour Hibernate pour ce faire, mais personnellement, je n'irais pas là-bas à moins que je ne l'aie absolument fait pour que JPA prenne en charge le schéma PostgreSQL existant qui reposait fortement sur l'héritage.