Arquitectura Java EE: ¿Todavía se recomiendan los DAO cuando se utiliza un ORM como JPA 2?

Si estoy usando un ORM como JPA2 – donde tengo mis entidades que están mapeadas en mi base de datos, ¿debería seguir usando un DAO? Parece mucho más sobrecargado.

Por ejemplo, necesitaría mantener tres paquetes adicionales:

  1. Uno que especifica mis objetos de dominio (que más o menos mapean mis objetos Entity):

    public class Employee { private String firstName; private String lastName; ... // Getters and setters } 
  2. Uno que contiene interfaces que especifican mis métodos DAO

     public interface EmployeeDAO { public void addEmployee(Employee employee); public Employee getEmployeeById(long id); ... } 
  3. Uno que contiene beans de sesión que implementan mi DAO

     public EmployeeJpaDAO implements EmployeeDAO { interface method implementations here .... private method that transform my Employee entity into my Employee domain object } 

Ahora eso es mucho equipaje extra para agregar cada vez que necesito realizar una nueva operación CRUD.

Sin embargo, los beneficios que veo al tener un DAO son:

  1. Puede tener una implementación en memoria del DAO para probar la capa de servicio de su unidad. Esto significa que no necesita acceder a la base de datos para probar la lógica comercial, y puede estar seguro de que sus objetos siempre contendrán los mismos valores para las propiedades.

  2. Separa la lógica de negocios de la lógica de acceso a la base de datos

La opción que no implica la implementación de un DAO es simplemente usar objetos de entidad y EntityManager en la capa de servicio:

 @Stateless public class EmployeeEjb { @PersistenceContext(unitName = "employee") private EntityManager manager; public Employee getEmployeeById(long id) { return manager.createNamedQuery(Employee.GetEmployeeById).getResultList(); } ... } 

¿No hay término medio aquí? ¿Alguien ha encontrado una architecture o implementado una architecture que cumple con algunos de los beneficios de una capa DAO (lo más importante es la capacidad de prueba de la lógica de negocios) que mencioné anteriormente, pero que no involucra todos los gastos indirectos involucrados para implementar una capa DAO?

Gracias por cualquier recomendación y / o sugerencia! Tengo mucha curiosidad por ver lo que algunas personas han pensado al respecto.

Si estoy usando un ORM como JPA2 – donde tengo mis entidades que están mapeadas en mi base de datos, ¿debería seguir usando un DAO? Parece mucho más sobrecargado.

Es. Y, claramente, Java EE no fomenta el uso del patrón DAO cuando se utiliza JPA (JPA ya proporciona una implementación estandarizada del patrón de la tienda de dominios y no hay mucho valor para protegerlo detrás de un DAO). Encuentro que el DAO es anti- DRY en tal situación.

Entonces, para casos simples (en realidad, la mayoría de los casos), felizmente omito el DAO y no tengo ningún problema con eso. Para casos más complejos (por ejemplo, al usar procedimientos almacenados, archivos planos), lo usaría. En otras palabras, depende, como se resume en ¿JPA ha matado al DAO? . Ver también las preguntas relacionadas a continuación:

Preguntas relacionadas

  • Encontré JPA, o similar, no aliento el patrón DAO
  • Patrón simple pero bueno para EJB
  • ¿Cuál es una buena estrategia para separar capas para una aplicación que se puede usar en línea y fuera de línea?
  • Usando JSF, JPA y DAO. Sin spring?
  • ¿Cuál es una estructura apropiada de DAO con jpa2 / eclipselink?

(…) Uno que contiene beans de sesión que implementan mis DAO’s

Noooo, ciertamente no quieres implementar un DAO como Session Bean:

  • No desea crear tantos Session Bean (agrupados) como tablas (grandes pérdidas de recursos)
  • No desea encaminar Session Beans a todas partes, no reproduzca errores del pasado, esta es una mala práctica conocida que no se escala bien.

Entonces, si realmente quiere seguir el camino de DAO y quiere que se le inyecte el EM, implemente sus DAO como Spring Bean (en Java EE 5) o CDI Bean administrado (en Java EE 6).

Puede tener una implementación en memoria del DAO para probar la capa de servicio de su unidad.

Si realmente desea realizar pruebas unitarias , simular DAO / EntityManager, no hay diferencia. Y si desea realizar pruebas de integración, puede configurar JPA para usar una base de datos en memoria. Entonces, al final, simplemente no compro este argumento.

Separa la lógica de negocios de la lógica de acceso a la base de datos

Honestamente, no veo una gran diferencia entre confiar en un DAO versus un gerente de entidad, no veo cómo un DAO separa las cosas “mejor”. Nuevamente, no compro este argumento.

Y para mi experiencia, cambiar la solución de persistencia subyacente es un evento muy excepcional y no voy a presentar DAO para algo que probablemente no vaya a suceder ( YAGNI , KISS ).

¿No hay término medio aquí? ¿Alguien ha encontrado una architecture o implementado una architecture que cumple con algunos de los beneficios de una capa DAO (lo más importante es la capacidad de prueba de la lógica de negocios) que mencioné anteriormente, pero que no involucra todos los gastos indirectos involucrados para implementar una capa DAO?

No veo mucho terreno intermedio y, como se insinuó fuertemente, no uso DAO si no siento la necesidad. Y como ya he dicho, EntityManager burla del EntityManager si quieres probar verdaderamente la lógica de la empresa. Funciona para mí y me complace escribir menos código.

Más recursos

  • JPA / EJB3 mató al DAO
  • Los DAO no están muertos, pero se derrumbaron o desaparecieron
  • … Y finalmente, debes presentar un DAO si:

Para el registro.

Para el principio de responsabilidad única (SRP), DAO es imprescindible , separa el modelo y la lógica en una capa de persistencia que puede transportarse fácilmente.

Si un proyecto usa la Unidad de prueba, DAO ayuda a probarlo correctamente (simulación, prueba de base de datos, etc.).

DAO es un SERVICIO y al igual que uno, podríamos ajustar nuestro proceso en una clase agradable que sea fácil de mantener.

JPA reduce el número de líneas de códigos pero, nada más, las reglas anteriores aún se aplican.

JPA trae una capa de repository pero no es NUESTRA capa de repository . En el mismo principio, digamos que encapsulamos una lógica que obtiene el beneficio de algún proceso. Puede ser que la encapsulación es simplemente una multiplicación para 0.1, pero aún es digno de encapsular.

Por ejemplo, digamos que tengo el siguiente problema: por alguna extraña razón, ¿puedo insertar un nuevo cliente en la base de datos ?. ¿Dónde debería empezar a probar? a: ClientDao si existe, si no, entonces buena suerte encontrando en otro lado.