Paso 3: CRUD Editorial - Book - Explicación del diseño
- Representaciones de los recursos en la capa de servicios
- Representación en la base de datos
- Diseño nuevos servicios
Al agregar la relación entre Book
y Editorial
, en este paso hemos introducido una representación detallada de editorial que contiene la colección de los libros que edita. Los servicios definidos en el paso-2 ahora reciben y devuelven esta nueva representación.
Adicionalmente, hemos agregado en este paso los servicios CRUD del recurso Book
y nuevos servicios para manipular desde editorial la relación con sus libros:
- Obtener los libros que una editorial edita,
- Agregar un libro a la editorial
- Eliminar un libro de la editorial
- Actualizar toda la colección de libros de una editorial.
La relación bidireccional entre Book
y Editorial
debe reflejarse tanto en las clases DTO
para hacer el mapping con los objetos json
, como en las clases Entity
para hacer el mapping con la base de datos.
Representaciones de los recursos en la capa de servicios
El diseño que hemos decidido con respecto a los DTO
es que cada recurso tiene dos representaciones:
1) La básica que contiene los atributos cuyo tipo es un tipo básico (String, Long, Boolean, etc.) y los atributos a otros recursos que representan una relación de cardinalidad 1. En nuestro ejemplo el atributo editorial que represente una relación de Book
a Editorial
: cada libro tiene asociada una única editorial.
2) La detallada que hereda de a básica y que contiene adicionalmente atributos que son colecciones de objetos de otros recursos. Por ejemplo books
atributo de la representación detallada de Editorial
que contiene una colección de objetos book en su representación básica.
Representación en la base de datos
Cada instancia de la clase BookEntity
tiene un atributo editorial
cuyo valor es una referencia a la instancia de la clase EditorialEntity
correspondiente. A su vez, cada instancia de la clase EditorialEntity
tiene un atributo books
cuyo valor es la colección de libros que la editorial edita.
El diagrama muestra estas relaciones. Para que haya un correcto mapping a la base de datos, debemos anotar los atributos de la relación con las anotaciones de JPA. Del lado de la clase BookEntity
el atributo editorial
va anotado con @ManyToOne
y del otro lado el atributo books
va anotado con @OneToMany
. Para indicar que se trata de la misma relación, en el lado @OneToMany
debemos indicar el nombre del atributo correspondiente, en este caso:
mappedBy = editorial
. En este caso, diremos que BookEntity
es el lado propietario de la relación (the owning side), significa que en la base de datos, en la tabla de BOOK cada fila guardará la llave foráneas de la editorial a la que pertenece.
Cuando JPA procesa la definición de las clases Entiy, construye el siguiente esquema de la base de datos:
Cada fila en BOOKENTITY
(cada objeto) tiene el atributo ID_EDITORIAL
que es la llave foránea que relaciona la tabla EDITORIALENTITY
.
Diseño nuevos servicios
Para los servicios del recurso nuevo Book
hemos creado una clase BookResource
y la clase de la representación básica BookDTO
. El diseño y la implementación de estos servicios son similares al CRUD del recurso EDITORIAL
en el paso-2. Se tiene en cuenta la relación de cardinalidad 1 tanto en los DTOS como en los ENTITY como se explicó más arriba.
Para los nuevos servicios del recurso EDITORIAL
relacionados con la colección de libros que cada editorial tiene, se diseñó un subrecurso EditorialBooksResource
. El propósito es, por un lado tener en una sola clase todos los servicios cuyo path comienza por:
editorials/{idEditorial}/books
Por otro lado, desde el recurso editorial, antes de invocar el subrecurso nuevo, se puede valida una sola vez si la editorial con identificar idEditorial
existe.
Las clases de recursos, representaciones y sus relaciones se muestran en la siguiente figura:
Note que la clase EditorialResource
invoca la clase EditorialBooksResource
. Tanto los servicios en la clase BookResource
como los servicios de la clase EditorialBooksResource
reciben y devuelven representaciones BookDetailDTO
. La diferencia entre los servicios está en que los primeros están restringidos a una editorial dada, es decir, los libros de una editorial mientras que los segundos se refieren a todos los libros en el sistema.