2010-01-26 14 views
9

Mam klasy jednostki i podklasy w oparciu o tej jednostki:JPA Język zapytań dla jednostki z dziedziczenia

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

i

@Entity 
public class B extends A 

muszę wydać natywną kwerendę, która korzysta z procedury przechowywanej tylko w klasie bazowej (A). Jeśli spróbuję wykonać to:

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

Pojawia się błąd dotyczący "kolumny clazz_ nie znaleziono w ResultSet". Zakładam, że dostawca JPA dodaje tę kolumnę w celu rozróżnienia między klasą podstawową a rozszerzoną. mogę obejść ten problem przez dodanie wyraźnie kolumnę clazz i wszystkich pól z podklasy:

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

gdzie „prop1” i „prop2” są właściwości podklasy B. Jednak wydaje się to niepotrzebne hack i jest podatny na problemy z utrzymaniem, jeśli podklasa B ulegnie zmianie.

Moje pytanie brzmi: Jak mogę wykonać zapytanie przy użyciu procedury przechowywanej na obiekcie, który ma zdefiniowane dziedzictwo?

Odpowiedz

9

Jak już zapewne widać, zespół Hibernate nie włożył dużo pracy w określaniu, jak to zrobić .. dokumentacja po prostu stwierdza:

16.1.6. Obchodzenie dziedziczenia

Native zapytań SQL, które zapytania dla podmiotów, które są mapowane jako część dziedziczenia musi obejmować wszystkie właściwości dla klasy bazowej i wszystkich jego podklasy.

Jeśli chcesz używać zapytań natywnych, wygląda na to, że utknąłeś w taki sposób. Jeśli chodzi o troskę o zmieniającym się podklasa B, być może nieco mniej uciążliwy sposób wykonania tego byłoby spróbować użyć LEFT OUTER JOIN składni na wspólnej działce ID:

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() 

ten sposób zawsze będziesz uzyskać wszystkie właściwości z B, jeśli dodasz lub usuniesz niektóre.

+0

Tak, myślałem o tym, ale problemem jest to, że po hibernacji próbuje nadmuchać obiekt z wyników i row, znajduje dwie kolumny id, z których jedna jest pusta. Przypuszczam, że mogę dodać dodatkową klauzulę where, w której filtry "b.id ma wartość null". – AnthonyF

+0

Pytanie brzmi: kiedy piszemy to w ten sposób, czy zawsze otrzymalibyśmy przypadki klasy B? –

Powiązane problemy