sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL-arv med JPA, Hibernate

JPA:s koncept för arv bygger på vanliga tabeller. Det "får" inte riktigt tanken på PostgreSQL:s tabellarv. Det är en av kostnaderna för att arbeta med en spec designad för att exponera den minsta gemensamma nämnaren av funktioner och göra det portabelt.

Se den här guiden för en anständig sammanfattning av JPA:s arvsstrategier. Observera att det i nyare Java 6 JavaDoc för @Inheritance finns en anteckning som säger att:

Om Arvsannoteringen inte är specificerad eller om ingen arvstyp anges för en entitetsklasshierarki, används SINGLE_TABLEmapping-strategin.

... och om du tittar på hur SINGLE_TABLE fungerar, det är inte konstigt att det inte fungerar för dig; det förväntar sig att alla underklasser ska finnas i ett stort bord med ett magiskt diskrimineringsvärde.

InheritanceType.TABLE_PER_CLASS är närmare hur Pg beter sig, men jag misstänker att JPA impl kommer att bli lite förvirrad när bastyptabellerna har poster för varje entitet av en bladtyp. Den försöker göra saker som UNION frågor över underklasstabellerna när man frågar på superklassen, och det kan ge udda resultat - åtminstone duplicering om UNION används och prestandaproblem om den använder UNION ALL . Beroende på exakt hur leverantören implementerar strategin kan det fungera åtminstone delvis. Du måste testa, och resultaten skulle möjligen vara ganska leverantörsspecifika.

En riktigt bra implementering av PG-arvsstöd för JPA skulle förmodligen kräva JPA-leverantörstillägg för en ny arvsstrategi som förstod PostgreSQL-tilläggen för arv och för ONLY frågor.

Om du kan övertyga din JPA-implementering att använda SELECT ... FROM ONLY subclass_table i InheritanceType.TABLE_PER_CLASS läge så borde det fungera OK med PostgreSQL-arv. Den skulle bara se de icke-ärvda raderna i varje tabell och arbeta med dem som om de vore vanliga tabeller. Din andra icke-JPA-kod kan sedan fortsätta använda arvsfunktionerna. Jag antar att det är möjligt att du kan ändra PostgreSQL-dialektkoden för Hibernate för att göra detta, men personligen skulle jag inte åka dit om jag inte absolut hade att få JPA att stödja befintligt PostgreSQL-schema som till stor del förlitade sig på arv.



  1. Hur använder jag ROW_NUMBER()?

  2. Hur man får sista raden per grupp i PostgreSQL

  3. Massinlägg med SQLAlchemy ORM

  4. Ersätter text i en BLOB-kolumn