2010-01-26 14 views
9

Ich habe eine Entity-Klasse und eine Unterklasse auf der Grundlage dieser Einheit:JPA Mutter Abfrage für Entity mit Vererbung

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public class A 

und

@Entity 
public class B extends A 

Ich brauche eine native Abfrage ausstellen, die eine gespeicherte Prozedur verwendet nur auf der Basisklasse (A). Wenn ich es versuchen, wie folgt:

entityManager.createNativeQuery("select * from A a where procedure(f)",A.class).getResultList() 

Ich erhalte eine Fehlermeldung in Bezug auf „Die Spalte clazz_ wurde nicht in der ResultSet gefunden“. Ich nehme an, dass der JPA-Provider diese Spalte hinzufügt, um zwischen der Basisklasse und der erweiterten Klasse zu unterscheiden. Ich kann durch explizites Hinzufügen der clazz Spalte und alle Felder aus der Unterklasse, um dieses Problem zu umgehen:

entityManager.createNativeQuery("select *,1 as clazz_,null as prop1,null as prop2 from A a where procedure(f)",A.class).getResultList() 

wo „PROP1“ und „prop2“ sind Eigenschaften der Unterklasse B. Dies scheint jedoch wie ein unnötiger hacken und neigt zu Wartungsproblemen, wenn sich die Unterklasse B ändert.

Meine Frage ist: Wie kann ich eine gespeicherte Prozedur für eine Entität abfragen, für die eine Vererbung definiert ist?

Antwort

9

Wie Sie wahrscheinlich gesehen haben, hat die Hibernate-Team nicht viel Arbeit setzen in die definieren, wie Sie dies tun .. die Dokumentation einfach erklärt:

16.1.6. Umgang mit Vererbungs

Native SQL-Abfragen, die Abfrage für Entitäten, die als Teil eines Vererbung abgebildet werden müssen alle Eigenschaften für die Basisklasse gehören und alle ihrer Unterklassen.

Wenn Sie also native Abfragen verwenden möchten, sieht es so aus, als ob Sie stecken bleiben. die Bedenken in Bezug auf über die Unterklasse B Wechsel, vielleicht etwas weniger belastende Art und Weise dies umzusetzen wäre, zu versuchen LEFT OUTER Syntax auf dem gemeinsam genutzten ID-Eigenschaft JOIN mit:

entityManager.createNativeQuery("select a.*, b*, 1 as clazz_, from A a LEFT OUTER JOIN B b on id = a.id where procedure(f)",A.class).getResultList() 

Auf diese Weise haben Sie immer alle das bekommen Eigenschaften von B, wenn Sie einige hinzufügen oder entfernen.

+0

So hatte ich daran gedacht, aber das Problem ist, dass, wenn Hibernate versucht, das Objekt aus den Resultaten aufzublasen et Zeile, es findet zwei ID-Spalten, von denen eine Null ist. Ich nehme an, ich kann eine zusätzliche where-Klausel hinzufügen, die die Filter aus 'b.id ist null' herausfiltert. – AnthonyF

+0

Die Frage ist: Wenn wir es so schreiben, würden wir immer Instanzen der Klasse B bekommen? –