Paso 4: CRUD Book - Review - Explicación del código

Anotaciones en las clases Entity

Las anotaciones en las clases Entity para indicar la relación entre Editorial y Book y entre Book y Editorial son las siguientes:

ReviewEntity

La clase ReviewEntity define un atributo para la relación con el libro al que pertenece. Este atributo tiene la anotación @ManyToOne para indicar que hay muchos reviews relacionados con el mismo libro pero un review pertenece a un único libro.

@Entity public class ReviewEntity extends BaseEntity implements Serializable { private String source; private String description; @ManyToOne private BookEntity book; ... }

BookEntity

La clase BookEntity define un atributo para la relación con la colección de reviews. Este atributo tiene la anotación @OneToMany para indicar que hay muchos reviews relacionados con el mismo libro.

@Entity public class BookEntity extends BaseEntity implements Serializable { private String isbn; private String image; @Temporal(TemporalType.DATE) private Date publishDate; private String description; @ManyToOne private EditorialEntity editorial; @OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true) private List<ReviewEntity> reviews = new ArrayList<ReviewEntity>(); ... }

Note que la anotación @OneToMany tiene varios atributos:

  1. mappedBy = "book" para indicar que esta relación que estamos definiendo se refiere a la misma que en la clase ReviewEntity está definida con el atributo "book". Con respecto a las tablas significa que es la tabla de reviews quien tiene la llave foránea al libro que corresponde.
  2. cascade = CascadeType.ALL significa que cualquier operación sobre un libro debe propagarse sobre cada una de sus reviews. En particular si un libro se borra se deben borrar todos sus reviews.
  3. orphanRemoval = true significa que no puede haber un reviews si no está asociado con un libro. No puede estar "huérfano".

Definición del subrecurso ReviewResource

La clase BookResource está anotada con el path books. Lo que significa que todos los servicios HTTP que tengan una url que comienza por:

urlsevidor/api/books se buscarán en este archivo.

... @Path("books") public class BookResource { ... }

La clase tiene definido el siguiente método:

... @Path("books") public class BookResource { ... @Path("{booksId: \\d+}/reviews") public Class<ReviewResource> getReviewResource(@PathParam("booksId") Long booksId) { BookEntity entity = bookLogic.getBook(booksId); if (entity == null) { throw new WebApplicationException("El recurso /books/" + booksId + " no existe.", 404); } return ReviewResource.class; } ... }

todos los servicios HTTP que tengan una url que comienza por:

urlsevidor/api/books/{booksId: \\d+}/reviews entrarán a este método que hacer dos cosas:

  1. Validar que el libro con identificador booksid exista. Si no existe, dispara la excepción.
  2. Redirecciona el llamado al subrecurso definido en la clase ReviewResource.

La clase ReviewResource no tiene un path al inicio de la clase pero todos los métodos anotados con GET/POST/PUT/DELETE deben declarar un parámetro:

@PathParam("booksId")Long booksId que corresponde con el path del método donde se redireccionó al subrecurso.

results matching ""

    No results matching ""