pattern patron generic diseño data java spring hibernate repository-pattern

java - patron - Patrón de repositorio: ¿cómo entenderlo y cómo funciona con entidades "complejas"?



spring data jpa (1)

Me está costando entender el patrón de repositorio.

Hay muchas opiniones sobre ese tema, como en Repository pattern right, pero también otras cosas como Repository es el nuevo Singleton o de nuevo en Doo use DAO use Repository o simplemente tome Spring JPA Data + Hibernate + MySQL + MAVEN donde de alguna manera un repositorio parece ser lo mismo que un objeto DAO.

Me estoy cansando de leer esto, porque esto no puede ser tan difícil como se muestra en muchos artículos.

Lo veo así: parece que lo que quiero es algo como esto:

------------------------------------------------------------------------ | Server | ------------------------------------------------------------------------ | | | | Client <-|-> Service Layer <-|-> Repository Layer <-|-> ORM / Database Layer | | | | | ------------------------------------------------------------------------

La Service Layer toma *DTO objetos *DTO y los pasa a la Repository Layer que básicamente no es más que "el tipo" que sabe cómo se puede almacenar una entidad.

Por ejemplo, supongamos que tiene una composición de algunas herramientas ( tenga en cuenta que esto es solo un pseudo código )

@Entity class ToolSet { @Id public Long id; @OneToOne public Tool tool1; @OneToOne public Tool tool2; } @Entity class Tool { @Id public Long id; @OneToMany public ToolDescription toolDescription; } @Entity class ToolDescription { @Id public Long id; @NotNull @OneToOne public Language language public String name; public String details; }

Lo que no entiendo es la parte en la que ToolSetDTO un objeto ToolSetDTO del cliente.

Como lo entendí hasta ahora, podría escribir un ToolSetRepository con un método ToolSetRepository.save(ToolSetDTO toolSetDto) que " sabe cómo almacenar " un ToolSetDTO . Pero casi todos los tutoriales no pasan el *DTO sino la Entity lugar.

Lo que me molesta aquí es que si toma mi ejemplo de ToolSet desde arriba, tendría que seguir los siguientes pasos:

  1. Toma toolSetDto y comprueba si no es null
  2. Para cada tool*Dto propiedad de toolSetDto
    a) Si tiene un id. válido, DTO de DTO a Entity contrario, cree una nueva entrada en la base de datos.
    b) toolDescriptionDto y convertirlo / guardarlo en la base de datos o crear una nueva entrada
  3. Después de verificar los de arriba, ToolSet (entidad) y ToolSet para conservarlo en la base de datos.

Todo esto es demasiado complejo como para permitir que la función de servicio (interfaz para el cliente) maneje esto.

Lo que estaba pensando era crear, por ejemplo, un ToolSetRepository pero la pregunta aquí es

  • ¿Toma un objeto de entidad ToolSet o usa un objeto DTO ?
  • En cualquier caso: ¿el *Repository puede usar otros objetos de repositorio? Como cuando quiero guardar ToolSet pero ToolSet tengo que almacenar Tool and ToolDescription . ¿ ToolRepository y ToolDescriptionRepository dentro de ToolSetRepository ?
    Si es así: ¿por qué no rompe el patrón de repositorio? Si este patrón es básicamente una capa entre el servicio y mi marco ORM, simplemente "no se siente bien" para agregar dependencias a otras clases *Repository debido a razones de dependencia.

No sé por qué no puedo entender esto. No parece tan complicado, pero todavía hay ayuda, como Spring Data . Otra cosa que me molesta es que realmente no veo cómo esto hace que todo sea ​​más fácil. Especialmente porque ya estoy usando Hibernate, no veo el beneficio (pero tal vez esa sea otra pregunta).

Entonces ... sé que esta es una pregunta larga, pero ya puse unos días de investigación al respecto. Ya estoy trabajando en un código en este momento que comienza a ser un desastre porque simplemente no puedo ver a través de este patrón.

Espero que alguien pueda darme una imagen más amplia que la mayoría de los artículos y tutoriales que no van más allá de implementar un ejemplo muy, muy simple de un Patrón de repositorio.


Puede leer mi post "repositorio para tontos" para comprender el principio simple del repositorio. Creo que su problema es que está trabajando con DTO y en ese escenario, realmente no usa el patrón de repositorio, está usando un DAO.

La diferencia principal entre un repositorio y un dao es que un repositorio devuelve solo objetos que la capa de llamada comprende . La mayoría de las veces, el repositorio es utilizado por la capa empresarial y, por lo tanto, devuelve objetos comerciales. Un dao devuelve datos que pueden ser o no un objeto comercial completo, es decir, los datos no son un concepto comercial válido.

Si sus objetos comerciales son solo estructuras de datos, podría ser una pista de que tiene un problema de modelado, es decir, un mal diseño. Un repositorio tiene más sentido con objetos ''ricos'' o al menos adecuadamente encapsulados. Si solo está cargando / guardando estructuras de datos, probablemente no necesite un repositorio, el orm es suficiente.

Si está tratando con objetos comerciales compuestos de otros objetos (un agregado) y ese objeto necesita todas sus partes para ser coherente (una raíz agregada), entonces el patrón de repositorio es la mejor solución porque abstrae todos los detalles de persistencia . Su aplicación solo pedirá un ''Producto'' y el repositorio lo devolverá como un todo, sin importar cuántas tablas o consultas se requieran para restaurar el objeto.

Según su muestra de código, no tiene objetos comerciales ''reales''. Usted tiene estructuras de datos utilizadas por Hibernate. Un objeto comercial está diseñado según los conceptos comerciales y los casos de uso. El repositorio permite que BL no se preocupe por la persistencia de ese objeto. De alguna manera, un repositorio actúa como un "conversor / mapeador" entre el objeto y el modelo que se mantendrá. Básicamente, el repositorio "reduce" los objetos a los datos requeridos para la persistencia.

Un objeto de negocio no es una entidad de ORM. Puede ser desde un punto de vista técnico, pero desde un punto de vista de diseño, uno modela cosas de negocios y otras cosas de persistencia de modelos. En muchos casos, estos no son directamente compatibles.

El mayor error es diseñar su objeto comercial de acuerdo con las necesidades de almacenamiento y la mentalidad. Y, al contrario de lo que muchos desarrolladores creen, un objetivo de ORM no es persistir en los objetos comerciales. Su propósito es simular una base de datos ''oop'' en la parte superior de un rdbms. El mapeo de ORM se realiza entre los objetos de db y las tablas, no entre los objetos de la aplicación (incluso menos cuando se trata de objetos comerciales) y las tablas.