openxava / documentación / Lección 6: Herencia de superclases mapeadas

Curso: 1. Primeros pasos | 2. Modelo básico del dominio (1) | 3. Modelo básico del dominio (2) | 4. Refinar la interfaz de usuario | 5. Desarrollo ágil | 6. Herencia de superclases mapeadas7. Herencia de entidades | 8. Herencia de vistas | 9. Propiedades Java | 10. Propiedades calculadas | 11. @DefaultValueCalculator en colecciones | 12. @Calculation y totales de colección | 13. @DefaultValueCalculator desde archivo | 14. Evolución del esquema manual | 15. Cálculo de valor por defecto multiusuario | 16. Sincronizar propiedades persistentes y calculadas | 17. Lógica desde la base de datos | 18. Validando con @EntityValidator | 19. Alternativas de validación  | 20. Validación al borrar  21. Anotación Bean Validation propia | 22. Llamada REST desde una validación  | 23. Atributos en anotaciones  | 24. Refinar el comportamiento predefinido | 25. Comportamiento y lógica de negocio | 26. Referencias y colecciones | A. Arquitectura y filosofía | B. Java Persistence API | C. Anotaciones | D. Pruebas automáticas

Tabla de contenidos

Lección 6: Herencia de superclases mapeadas
Superclase mapeada
Simplificar tus entidades
Resumen
La herencia es una forma práctica de reutilizar el código en el mundo de la orientación a objetos. Usar herencia con JPA y OpenXava es tan fácil como hacerlo con puro Java. Vamos a usar la herencia para quitar el código repetitivo y aburrido, como la definición de los UUID, esto lo haremos usando superclases mapeadas de JPA.
Si no te gustan los videos sigue las instrucciones a continuación.

Superclase mapeada

Las clases Autor, Categoria y Factura tienen algo de código en común. Este código es la definición del campo oid:
@Id @GeneratedValue(generator="system-uuid") @Hidden
@GenericGenerator(name="system-uuid", strategy = "uuid")
@Column(length=32)
String oid;
Este código es exactamente el mismo para todas estas clases. Ya sabes que copiar y pegar es un pecado mortal, por eso tenemos que buscar una forma de quitar este código repetido y así evitar ir al infierno.
Una solución elegante en este caso es usar herencia. JPA permite varias formas de herencia. Una de ellas es heredar de una superclase mapeada. Una superclase mapeada es una clase Java con anotaciones de mapeo JPA, pero no es una entidad en sí. Su único objetivo es ser usada como clase base para definir entidades. Usemos una y verás su utilidad rápidamente.
Primero, movemos el código común a una clase marcada como @MappedSuperclass. La llamamos Identificable:
package com.tuempresa.facturacion.modelo;
 
import javax.persistence.*;
import org.hibernate.annotations.GenericGenerator;
import org.openxava.annotations.*;
import lombok.*;
 
@MappedSuperclass // Marcada como una superclase mapeada en vez de como una entidad
@Getter @Setter
public class Identificable {
 
    @Id @GeneratedValue(generator="system-uuid") @Hidden
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    @Column(length=32)
    String oid; // La definición de propiedad incluye anotaciones de OpenXava y JPA
 
}

Simplificar tus entidades

Ahora puedes definir las entidades Autor, Categoria y Factura de una manera más sucinta. Para ver un ejemplo aquí tienes el nuevo código para Categoria:
package com.tuempresa.facturacion.modelo;
 
import javax.persistence.*;
import lombok.*;
 
@Entity @Getter @Setter
public class Categoria extends Identificable { // Extiende de Identificable
                        // por tanto no necesita tener una propiedad id
    @Column(length=50)
    String descripcion;
  
}
La refactorización es extremadamente simple. Categoria ahora desciende de Identificable y hemos quitado la propiedad oid. De esta forma, no sólo tu código es más corto, sino también más elegante, porque estás declarando tu clase como identificable (el qué, no el cómo), y has quitado de tu clase de negocio un código que era un tanto técnico.
Aplica esta misma refactorización a las entidades Autor y Factura. Además, a partir de ahora extenderás la mayoría de tus entidades de la superclase mapeada Identificable.

Hemos creado nuestra propia clase Identificable para ver las ventajas de usar superclases mapeadas, sin embargo OpenXava te provee una clase Identifiable lista para usar que puedes encontrar en el paquete org.openxava.model. Por tanto, en tu próximo proyecto no has de escribir la clase Identificable otra vez, simplemente usa la incluida en OpenXava.

Resumen

Has aprendido, pues, que una superclase mapeada es una clase normal y corriente con anotaciones de mapeo JPA que puedes usar como clase base para tus entidades. También has aprendido como usar una superclase mapeada para simplificar tu código.

Descargar código fuente de esta lección

¿Problemas con la lección? Pregunta en el foro ¿Ha ido bien? Ve a la lección 7