2009-09-15 12 views
9

Problema

Tengo un @MappedSuperclass llamada de datos como el padre de toda entidad en mi base de datos. Contiene atributos comunes como Id. Luego tengo una entidad que extiende Datos que también es @MappedSuperclass debido a la funcionalidad común de sus subclases. La asignación en mi base de datos es correcta.Selección MappedSuperclass de la base de datos (Hibernate)

Aquí es un ejemplo de mi jerarquía

 
@MappedSuperclass 
Data 
| @MappedSuperclass 
+- Employee 
|  | @Entity 
|  +- FullTimeEmployee 
|  | @Entity 
|  +- PartTimeEmployee 
| @Entity 
+- Store 

y las mesas están bien mapeados:

 
FullTimeEmployee 
PartTimeEmployee 
Store 

¿Hay alguna forma para consultar la base de datos para todas las subclases de los empleados (FullTimeEmployee, PartTimeEmployee) como instancias del empleado sin referir el nombre de las subclases en la consulta?

Algo así como

List<Employee> allEmployees = getAllEmployees(); 

La idea es que cada vez que decido crear otra subclase de empleados (es decir, AllDayEmployee) no voy a tener que cambiar la consulta para incluir el nombre.


Solución

Así que, como Gregory de manifiesto acertadamente, esto no es posible con @MappedSuperclass. Así que lo cambié a @Entity y, como quería preservar una tabla para cada subclase, usé InheritanceType.JOINED.

Así que la jerarquía anterior es ahora

 
@MappedSuperclass 
Data 
| @Entity 
| @Inheritance(strategy=InheritanceType.JOINED) 
+- Employee 
|  | @Entity 
|  +- FullTimeEmployee 
|  | @Entity 
|  +- PartTimeEmployee 
| @Entity 
+- Store 

y las mesas están todavía:

 
FullTimeEmployee 
PartTimeEmployee 
Store 

Así que ahora, para obtener todos los empleados que simplemente llamo:

entityManager.createQuery("from Employee").getResultList(); 
+0

¿y si necesito dos 'SequenceGenerator' @ diferente para FullTimeEmployee y PartTimeEmployee (estoy usando Oracle secuencias)? Al ser una Entidad, debo especificar el '@ Id' en la clase Empleado. – drakyoko

Respuesta

8

No se si está utilizando @MappedSuperclass

La razón de esto es que cuando se define como clase base @MappedSuperclass, no existe una tabla generada para la clase base, en lugar de todas las propiedades se replican en el hormigón mesas. En su ejemplo, solo existirían las tablas FullTimeEmployee, PartTimeEmployee y Store.

Si desea poder consultar entidades de clase base, debe seleccionar una asignación diferente para las clases base. Use la anotación @Heritage en la clase base y seleccione una de las 3 estrategias de mapeo posibles - SINGLE TABLE, TABLE PER CLASS o JOINED

0

FROM Employee WHERE Employee.<employee only properties> = someValue 

Pero solo, como los otros han dicho aquí, si la entidad Empleado está mapeada. No es necesario que incluso lo asigne a su propia mesa. Vea las estrategias de mapeo en Hibernate.

+0

+1 Sí. En Hibernate, puede seleccionar una clase abstracta, también obtendrá todas las subclases. El ejemplo dado es consultar para Object, que devolverá toda la base de datos. :-) – KLE

+0

Dado que Employee es una clase abstracta que tiene una anotación @MappedSuperclass, quiero obtener todas las instancias de subclase de Employee. La consulta "desde el empleado" arroja una QuerySyntaxException: el empleado no está mapeado " – pek

+0

Consulte mi respuesta para saber por qué no funcionará con @MappedSuperclass –

0

Me parece ser capaz de hacer esto (aunque usando InheritanceType.JOINED) con hibernate 5.0.8 , java 1.8.0_73 y Oracle 12c - o bien estoy malentendido o quizás hibernate ha cambiado ...

tengo el siguiente hierarhcy:

@MappedSuperclass 
@Inheritance(strategy=InheritanceType.JOINED) 
CommonRoot 
| 
| @MappedSuperclass 
+- Mapped 
     | @Entity(name="Concrete1") 
     | @Table(name="CON1") 
     +- Concrete1 
     | 
     | @Entity(name="Concrete2") 
     | @Table(name="CON2") 
     +- Concrete2 

Y puedo hacer lo siguiente HQL:

SELECT entityId FROM com.hibernatetest.Mapped ORDER BY entityId ASC 

que da estas declaraciones 2 SQL:

select concrete2x0_.entityId as col_0_0_ from CON2 concrete2x0_ order by concrete2x0_.entityId ASC 
select concrete1x0_.entityId as col_0_0_ from CON1 concrete1x0_ order by concrete1x0_.entityId ASC 

y la advertencia

WARN: HHH000180: FirstResult/maxResults specified on polymorphic query; applying in memory! 

No está seguro de lo que significan, sin embargo, ya que esto se puede hacer con SQL como:

(select entityId from CON2 
union all 
select entityId from CON1) 
order by entityId ASC 

(Y también se puede agregar cláusulas límite/ROWNUM para que si lo desea, a pesar de que se hace un poco torpe:

select * from (
(select * from (select entityId from CON2 order by entityId ASC) where rownum <= 10) 
UNION ALL 
(select * from (select entityId from CON1 order by entityId ASC) where rownum <= 10) 
) where rownum <= 10 order by entityId ASC 

no sé por qué hibernación no debería ser capaz de hacer esto -. podría sugerir a ellos)

Cuestiones relacionadas