2010-09-30 19 views
32

¿Cómo configuraría las anotaciones en el siguiente código de ejemplo? Me gustaría seguir con las anotaciones de JPA y evitar las dependencias específicas de Hibernate. ¿El código de abajo es correcto?Clase abstracta heredada con JPA (+ Hibernate)

@Entity 
public class RefExample extends RefData { 

} 

(Habrá varias versiones de estas clases, RefSomeOtherExample, etc, y una mesa de un dB por clase. Algunos pueden añadir campos adicionales (columnas), pero la mayoría de ellos simplemente hacer uso de los campos básicos heredado de la "rEFDATA" clase base)

clase base:.

@Entity 
public abstract class RefData { 

    private long id; 
    private String code; 
    private String desc; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(unique = true, nullable = false) 
    public long getId() { 

     return id; 
    } 

    public void setId(long id) { 

     this.id = id; 
    } 

    @Column(unique = true, nullable = false, length=8) 
    public String getCode() { 

     return code; 
    } 

    public void setCode(String code) { 

     this.code = code; 
    } 

    @Column(unique = true, nullable = false, length=80) 
    public String getDesc() { 

     return desc; 
    } 

    public void setDesc(String desc) { 

     this.desc = desc; 
    } 
} 

en última instancia me gustaría generar secuencias de comandos de creación del esquema de esta clase usando SchemaExport de Hibernate. En el caso anterior, estas dos clases solo deberían dar como resultado la creación de una única tabla llamada "RefExample" con las tres columnas de "RefData". esto funcionara?

Respuesta

75

De la especificación JPA 1.0:

Ambas clases abstractas y concretas pueden ser entidades. Tanto las clases abstractas como las concretas se pueden anotar con la anotación Entidad, asignadas como entidades y consultadas como entidades.

Las entidades pueden ampliar las clases sin entidad y las clases sin entidad pueden extender las clases de entidad.

Como quiera una sola tabla, debe usar la herencia Single Table.

apenas define una columna discriminadora de la siguiente manera:

@Entity 
@DiscriminatorColumn(name="REF_TYPE") 
public abstract class RefData { 

Pero si no quiere depender de las estrategias de herencia de la APP, puede utilizar MappedSuperclass lugar:

@MappedSuperclass 
public abstract class RefData { 

especificación JPA

Una entidad puede heredar de una superclase que proporciona información persistente estado de la entidad y la asignación, pero w que no es en sí mismo una entidad. Típicamente, el propósito de dicha superclase mapeada es definir información de estado y mapeo que es común a múltiples clases de entidad.

Tenga en cuenta no se puede uso @Entity y @MappedSuperclass al mismo tiempo.

+0

@Crusader Vea aquí: http://stackoverflow.com/questions/2700680/table-per-subclass-inheritance-relationship-how-to-query-against-the-parent-clas/3017146#3017146 cómo soluciono los problemas de rendimiento cuando se trata de herencia. ** Si desea utilizar la estrategia TABLE PER CLASS, la base de datos de destino debe admitir la estrategia de generación de identidad **. –

+1

Todavía no estoy 100% seguro, pero creo que MappedSuperclass puede ser mi mejor opción. Todas estas tablas son realmente para almacenar los valores presentados en los campos desplegables que se asignan (uno a muchos) a los registros de datos reales. – Manius

+0

Es posible consultar (HQL o JPQL) en las propiedades presentes en la superclase anotada con @MappedSuperclass – Sunil

0

Puede usar una de las estrategias de herencia para esto. Su caso parece ser el caso de una sola clase para la jerarquía.

Comprobar this

+1

Ese artículo me tiene perplejo. En realidad estaba imaginando la tabla por la estrategia de clase concreta descrita allí (una tabla por clase concreta "RefExample"), pero dice que el enfoque es "no popular" Y opcional en JPA. Ninguna de las tres opciones parece ajustarse exactamente a mis requisitos. ¡Ratas! – Manius

5

@MappedSuperClass me funcionó. Estaba luchando por asignar una vista a 2 objetos que son clases principales y secundarias. Mi vista está unida desde 2 tablas. Las claves primarias de ambas tablas están presentes en la vista.@DiscriminatorColumn no funciona para mí ya que requiere una columna asignada exclusivamente al tipo de datos del objeto y también arroja 'repeated Column in object exception' que no pude resolver.

He leído este foro y probé @MappedSuperClass anotación. Lo hace el truco.

He puesto @MappedSuperclass en la superclase y poner el @Id y @GeneratedValue en el identificador superclase. En la subclase que he dado como

@Entity 
@Table(name="view_name") 

y utilicé el objeto de clase secundaria para obtener los datos de la vista. Eso es.

Herencia en las anotaciones de hibernación para la tabla Unida sin usar @DiscriminatorColumn funcionó para mí.

Gracias.