PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Ereditarietà PostgreSQL con JPA, Hibernate

Il concetto di eredità di JPA si basa su tabelle ordinarie. In realtà non "capisce" l'idea dell'ereditarietà delle tabelle di PostgreSQL. Questo è uno dei costi di lavorare con una specifica progettata per esporre il minimo comune denominatore di funzionalità e farlo in modo portatile.

Consulta questa guida per un riepilogo decente delle strategie di eredità di JPA. Nota che nel JavaDoc Java 6 più recente per @Inheritance c'è una nota che dice che:

Se l'annotazione Ereditarietà non è specificata o se non è specificato alcun tipo di ereditarietà per una gerarchia di classi di entità, viene utilizzata la strategia di mappatura SINGLE_TABLE.

... e se guardi come SINGLE_TABLE funziona, non sorprende che non funzioni per te; si aspetta che tutte le sottoclassi siano in una grande tabella con un valore discriminatore magico.

InheritanceType.TABLE_PER_CLASS è più vicino a come si comporta Pg, ma sospetto che l'impl JPA si confonderà un po' quando le tabelle dei tipi di base hanno voci per ogni entità di un tipo foglia. Prova a fare cose come UNION query sulle tabelle delle sottoclassi durante l'esecuzione di query sulla superclasse e ciò potrebbe produrre risultati dispari, almeno duplicazione se UNION viene utilizzato e problemi di prestazioni se utilizza UNION ALL . A seconda di come il provider implementa esattamente la strategia, potrebbe funzionare almeno in parte. Dovresti eseguire un test e i risultati potrebbero essere abbastanza specifici del provider.

Un'implementazione davvero buona del supporto dell'ereditarietà PG per JPA richiederebbe probabilmente estensioni del provider JPA per una nuova strategia di ereditarietà che comprendesse le estensioni PostgreSQL per l'ereditarietà e per ONLY domande.

Se riesci a convincere la tua implementazione JPA a usare SELECT ... FROM ONLY subclass_table quando in InheritanceType.TABLE_PER_CLASS modalità quindi dovrebbe interoperare OK con l'ereditarietà di PostgreSQL. Vedrebbe solo le righe non ereditate in ogni tabella e lavorerebbe con esse come se fossero tabelle normali. L'altro codice non JPA potrebbe quindi continuare a utilizzare le funzionalità di ereditarietà. Immagino che tu possa modificare il codice del dialetto PostgreSQL per Hibernate per farlo, ma personalmente non ci andrei a meno che non avessi assolutamente per fare in modo che JPA supporti lo schema PostgreSQL esistente che si basava fortemente sull'ereditarietà.