2010-01-26 12 views
9

tengo una clase de entidad y una subclase basado en esa entidad:APP nativa de consulta para la Entidad con la herencia

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

y

@Entity 
public class B extends A 

I necesidad de emitir una consulta nativa que utiliza un procedimiento almacenado en la clase base (A) solamente. Si lo intento de la siguiente manera:

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

consigo un error con respecto a "El clazz_ columna no se encontró en el conjunto de resultados". Supongo que el proveedor de JPA agrega esta columna para discriminar entre la clase base y la clase extendida. Puedo solucionar este problema mediante la adición de forma explícita la columna de la clazz y todos los campos de la subclase:

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

donde "prop1" y "prop 2" son propiedades de la subclase B. Sin embargo, esto parece una innecesaria piratear y es propenso a problemas de mantenimiento si la subclase B cambia.

Mi pregunta es: ¿cómo puedo consultar utilizando un procedimiento almacenado en una entidad que tiene herencia definida en él?

Respuesta

9

Como usted probablemente ha visto, el equipo de hibernación no se ha puesto un montón de trabajo en la definición de cómo hacer esto .. la documentación indica simplemente:

16.1.6. Manejo de la herencia

consultas SQL nativas, que consulta por entidades que se asignan como parte de una herencia debe incluir todos los propiedades de la clase base y todos los sus subclases.

Así que si quieres usar consultas nativas, parece que estás atascado haciendo algo como esto. En cuanto a la preocupación por el cambio de la subclase B, tal vez de manera un poco menos onerosa de implementar esto sería tratar de usar LEFT OUTER JOIN sintaxis en la propiedad compartida 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() 

esa manera que siempre obtendrá la totalidad de la propiedades desde B si agrega o elimina algunas.

+0

Por lo tanto, yo había pensado en esto, pero el problema es que cuando Hibernate intenta inflar el objeto de los Resultados et row, encuentra dos columnas de id, una de las cuales es nula. Supongo que puedo agregar una cláusula where adicional donde los filtros 'b.id sea nulo'. – AnthonyF

+0

La pregunta es: cuando lo escribimos de esta manera, ¿siempre obtendríamos instancias de clase B? –

Cuestiones relacionadas