2010-01-26 18 views
9

Ho una classe di entità e di una sottoclasse basata su tale entità:JPA nativo di query per entità con l'ereditarietà

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

e

@Entity 
public class B extends A 

Ho bisogno di emettere una query nativo che utilizza una stored procedure solo sulla classe base (A). Se tento come segue:

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

ottengo un errore "Il clazz_ colonna non è stato trovato nel ResultSet". Presumo che il provider JPA aggiunga questa colonna per discriminare tra la classe base e la classe estesa. Posso aggirare il problema aggiungendo esplicitamente la colonna Clazz e tutti i campi dalla sottoclasse:

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

dove "prop1" e "prop2" sono proprietà della sottoclasse B. Tuttavia, questo sembra un inutile hack ed è soggetto a problemi di manutenzione se la sottoclasse B cambia.

La mia domanda è: come posso interrogare usando una stored procedure su un'entità che ha ereditato su di essa?

risposta

9

Come probabilmente avete visto, la squadra Hibernate non ha messo un sacco di lavoro in definire come si esegue questa operazione .. la documentazione afferma semplicemente:

16.1.6. Manipolazione eredità

query SQL nativi che query per entità che sono mappati come parte di un eredità deve includere tutte le proprietà per la baseclass e tutti sue sottoclassi.

Quindi, se si desidera utilizzare le query native, sembra che si è bloccato fare qualcosa di simile. Per quanto riguarda la preoccupazione per il cambiamento sottoclasse B, forse un modo un po 'meno oneroso di applicazione del presente sarebbe quello di provare a utilizzare LEFT OUTER JOIN sintassi sulla proprietà ID comune:

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

In questo modo avrete sempre tutto il proprietà da B se ne aggiungi o ne rimuovi alcune.

+0

Così, avevo pensato a questo, ma il problema è che quando Hibernate tenta di gonfiare l'oggetto dai risultati et row, trova due colonne id, una delle quali è null. Suppongo di poter aggiungere un'ulteriore clausola where che filtri 'b.id è null'. – AnthonyF

+0

La domanda è: quando la scriviamo in questo modo, otterremmo sempre istanze di classe B? –

Problemi correlati