openxava / documentación / Lección 2: Modelo básico del dominio - Parte 1

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 mapedas | 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 2: Modelo básico del dominio - Parte 1
Modelo del dominio
Referencia (ManyToOne) como lista de descripciones (combo)
Anotaciones
Embeddable
Resumen
En esta lección, empezarás a crear las entidades de tu proyecto para tener tu aplicación de facturación funcionando.
Asumimos que sabes crear una nueva entidad con OpenXava Studio y como ejecutar la aplicación, porque ya has leído la lección 1.
Si no te gustan los videos sigue las instrucciones a continuación.

Modelo del dominio

Primero crearemos las entidades para tu aplicación facturacion. El modelo del dominio es más bien básico, pero suficiente para aprender bastantes cosas interesantes:
modeling_es010.png
Empezaremos con seis clases, y más adelante añadiremos algunas más. Recuerda que ya tienes una versión inicial de Cliente y Producto.

Referencia (ManyToOne) como lista de descripciones (combo)

Empecemos con el caso más simple. Vamos a crear una entidad Categoria y asociarla a Producto, visualizándola con un combo.
El código para la entidad Categoria es:
package com.tuempresa.facturacion.modelo;
 
import javax.persistence.*;
import org.hibernate.annotations.GenericGenerator;
import org.openxava.annotations.*;
import lombok.*;
 
@Entity @Getter @Setter
public class Categoria {
 
    @Id
    @Hidden // La propiedad no se muestra al usuario. Es un identificador interno
    @GeneratedValue(generator="system-uuid") // Identificador Universal Único (1)
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    @Column(length=32)
    String oid;
 
    @Column(length=50)
    String descripcion;
 
}
Sin duda, la entidad más simple posible. Solo tiene un identificador y una propiedad descripcion. En este caso usamos el algoritmo Identificador Universal Único (1) para generar el identificador. La ventaja de este generador de identificadores es que puedes migrar tu aplicación a otras bases de datos (DB2, MySQL, Oracle, Informix, etc) sin tocar tu código. Los otros generadores de identificadores de JPA usan la base de datos para generar el identificador, por lo que no son tan portables como UUID.
Ahora puedes ejecutar el módulo Categoria y añadir algunas categorías:
modeling_es035.png
Lo siguiente sería asociar Producto con Categoria: Añade la siguiente declaración para la referencia categoria en tu entidad Producto:
public class Producto {
 
    ...
 
    @ManyToOne( // La referencia se almacena como una relación en la base de datos
        fetch=FetchType.LAZY, // La referencia se carga bajo demanda
        optional=true) // La referencia puede estar sin valor
    @DescriptionsList // Así la referencia se visualiza usando un combo
    Categoria categoria; // Una referencia Java convencional
 
}
Es una simple relación muchos-a-uno de JPA, como se puede ver en el apéndice B. En este caso, gracias a la anotación @DescriptionsList se visualiza usando un combo:
modeling_es020.png
Ahora es el momento de completar la entidad Producto.

Anotaciones

La entidad Producto necesita tener al menos precio, además estaría bien que tuviese fotos y un campo para observaciones. Vamos a usar anotaciones para conseguirlo. Las anotaciones son como etiquetas para el código, es una forma de añadir metadatos a nuestro código, como en variables, métodos, clases, paquetes, entre otros.
La mejor forma de entender que es una anotación es verlo en acción. Añadamos las propiedades precio, fotos y observaciones a tu entidad Producto:
@Money // La propiedad precio se usa para almacenar dinero
BigDecimal precio; // BigDecimal se suele usar para dinero
 
@Files // Una galería de fotos completa está disponible
@Column(length=32) // La cadena de 32 de longitud es para almacenar la clave de la galería
String fotos;
 
@TextArea // Esto es para un texto grande, se usará un área de texto o equivalente
String observaciones;
Has visto como usar anotaciones, solo debes escribir la anotación y OpenXava hará un tratamiento especial. Si ejecutas el módulo para Producto ahora verás lo siguiente:
modeling_es040.png
En este caso usamos algunas de las anotaciones que están incluidas dentro de OpenXava, puedes notar que cada una produce un efecto en la interfaz de usuario.
Algunas de las anotaciones disponibles son @Password, @Money, @TextArea, @Label, @DateTime, @Discussion, @Icon, @Telephone, @IP, @EmailList, @MAC , @StringTime, @HtmlText, @Coordinates, @Files, @File, etc. Para más información puedes ver aquí, donde se habla más sobre anotaciones.
Ya tienes Producto listo. Refinemos ahora Cliente.

Embeddable

Vamos a añadir una dirección a nuestro, hasta ahora algo desnudo, Cliente. La dirección del Cliente no está compartida por otros objetos Cliente, es decir, cuando un cliente se borra, su dirección es borrada también, por lo tanto modelaremos el concepto de dirección como una clase incrustable. Esto se puede ver en el apéndice B sobre JPA.
Añade la clase Direccion a tu proyecto:
package com.tuempresa.facturacion.modelo;
 
import javax.persistence.*;
import lombok.*;
 
@Embeddable // Usamos @Embeddable en vez de @Entity
@Getter @Setter
public class Direccion {
 
    @Column(length = 30) // Los miembros se anotan igual que en las entidades
    String viaPublica;
 
    @Column(length = 5)
    int codigoPostal;
 
    @Column(length = 20)
    String municipio;
 
    @Column(length = 30)
    String provincia;
 
}
Como ves, es una clase normal y corriente anotada como @Embeddable. Sus propiedades se anotan de la misma manera que en las entidades, aunque las clases incrustables no soportan toda la funcionalidad de las entidades.
Ahora, puedes usar Direccion en cualquier entidad. Simplemente añade una referencia a ella en tu entidad Cliente:
public class Cliente {
 
    ...
 
    @Embedded // Así para referenciar a una clase incrustable
    Direccion direccion; // Una referencia Java convencional
 
}
Los datos de Direccion se almacenan en la misma tabla que los de Cliente. Y desde una perspectiva de la interfaz de usuario hay un marco alrededor de Direccion, aunque si no te gusta el marco sólo has de anotar la referencia con @NoFrame, como se muestra aquí:
@Embedded @NoFrame // Con @NoFrame no se muestra marco para direccion
private Direccion direccion;
Aquí se muestra la interfaz de usuario para una referencia incrustada con y sin @NoFrame:
modeling_es060.png

Resumen

Esta lección te ha enseñado como definir referencias que se visualizan como combos con @DescriptionsList, como usar los anotaciones y los @Embeddable. Ahora que tenemos las entidades básicas en marcha, es el momento de enfrentarnos a la entidad principal de la aplicación: Factura. Hagámoslo poco en la siguiente lección.

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 3