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 mapeadas | 7. 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.

Superclase mapeada

Las clases Author, Category e Invoice tienen algo de código en común. Este código es la definición del campo oid:
@Id @GeneratedValue(strategy=GenerationType.UUID) @Hidden
@Column(length=36)
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 Identifiable:
package com.yourcompany.invoicing.model;
 
import jakarta.persistence.*;
import org.openxava.annotations.*;
import lombok.*;
 
@MappedSuperclass // Marcada como una superclase mapeada en vez de como una entidad
@Getter @Setter
public class Identifiable {
 
    @Id @GeneratedValue(strategy=GenerationType.UUID) @Hidden
    @Column(length=36)
    String oid; // La definición de propiedad incluye anotaciones de OpenXava y JPA
 
}

Simplificar tus entidades

Ahora puedes definir las entidades Author, Category e Invoice de una manera más sucinta. Para ver un ejemplo aquí tienes el nuevo código para Category:
package com.yourcompany.invoicing.model;
 
import jakarta.persistence.*;
import lombok.*;
 
@Entity @Getter @Setter
public class Category extends Identifiable {
  
    @Column(length=50)
    String description;
 
}
La refactorización es extremadamente simple. Category ahora desciende de Identifiable 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 Author e Invoice. Además, a partir de ahora extenderás la mayoría de tus entidades de la superclase mapeada Identifiable.

Hemos creado nuestra propia clase Identifiable 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 Identifiable 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.

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