Pergunta

Se estou usando um ORM como o JPA2 - onde tenho minhas entidades mapeadas para o meu banco de dados, ainda devo usar um DAO? Parece muito mais sobrecarga.

Por exemplo, eu precisaria manter três pacotes extras:

  1. Um que especifica meus objetos de domínio (que praticamente mapeiam meus objetos de entidade):

    public class Employee {
        private String firstName;
        private String lastName;
        ...
        // Getters and setters
    }
    
  2. Um que contém interfaces que especificam meus métodos DAO

    public interface EmployeeDAO {
        public void addEmployee(Employee employee);
        public Employee getEmployeeById(long id);
        ...
    }
    
  3. Um que contém grãos de sessão que implementam o meu dao

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

Agora, isso é muita bagagem extra para adicionar toda vez que preciso realizar uma nova operação CRUD.

No entanto, os benefícios que vejo por ter um DAO são:

  1. Você pode ter uma implementação na memória do DAO para testar sua camada de serviço. Isso significa que você não precisa acessar o banco de dados para testar a lógica dos negócios e pode ter certeza de que seus objetos sempre conterão os mesmos valores para propriedades

  2. Ele separa a lógica de negócios da lógica de acesso ao banco de dados

A opção que não envolve a implementação de um DAO é apenas usar objetos de entidade e entityManager na camada de serviço:

@Stateless
public class EmployeeEjb {
    @PersistenceContext(unitName = "employee")
    private EntityManager manager;

    public Employee getEmployeeById(long id) {
        return manager.createNamedQuery(Employee.GetEmployeeById).getResultList();
    }
    ...
}

Não há meio termo aqui? Alguém se deparou com uma arquitetura ou implementou uma arquitetura que atenda a alguns dos benefícios de uma camada DAO (o mais importante é a testabilidade da unidade da lógica de negócios) que mencionei acima, mas não envolve toda a sobrecarga envolvida para implementar uma camada DAO?

Obrigado por quaisquer recomendações e/ou sugestões! Estou realmente curioso para ver o que algumas pessoas criaram em relação a isso.

Foi útil?

Solução

If I'm using an ORM like JPA2 - where I have my entities that are mapped to my database, should I still be using a DAO? It seems like a lot more overhead.

It is. And clearly, Java EE doesn't encourage using the DAO pattern when using JPA (JPA already provides a standardized implementation of the Domain Store pattern and there isn't much value at shielding it behind a DAO). I find the DAO to be anti-DRY in such situation.

So for simple cases (actually, most cases), I happily skip the DAO and I have no problem with that. For more complex cases (for example when using stored procedures, flat files), I'd use it. In other words, it depends, as summarized in Has JPA Killed the DAO?. See also the related questions below:

Related questions

(...) One that contains session beans that implement my DAO's

Noooo, you certainly don't want to implement a DAO as a Session Bean:

  • You don't want to create as much (pooled) Session Bean as tables (big waste of resources)
  • You don't want to chain Session Beans everywhere, don't reproduce errors from the past, this is a known bad practice that doesn't scale well.

So if you really want to go the DAO way and want the EM to be injected, either implement your DAOs as Spring beans (in Java EE 5) or CDI managed bean (in Java EE 6).

You can have an in memory implementation of the DAO for unit testing your service layer.

If you really want to do unit testing, mock the DAO/EntityManager, there is no difference. And if you want to do integration testing, you can configure JPA to use an in memory database. So at the end, I just don't buy this argument.

It separates business logic from database access logic

Honestly, I don't see a big difference between relying on a DAO vs an entity manager, I don't see how a DAO separate things "better". Again, I don't buy this argument.

And to my experience, changing the underlying persistence solution is a very exceptional event and I'm not going to introduce DAOs for something that is very likely not going to happen (YAGNI, KISS).

Is there no middle ground here? Has anyone come across an architecture or implemented an architecture that meets some of the benefits of a DAO layer (most importantly the unit testability of business logic) that I mentioned above, but doesn't involve all the overhead involved to implement a DAO layer?

I don't see much middle ground and, as strongly hinted, I don't use DAOs if I don't feel the need. And as I said, mock the EntityManager if you want to truly unit test the business logic. It works for me and I'm happy to write less code.

More resources

Outras dicas

Para constar.

Para o princípio de responsabilidade única (SRP), Dao é um deve ter, ele separa o modelo e a lógica em uma camada de persistência que pode ser facilmente portátil.

Se um projeto estiver usando a unidade de teste, o DAO ajuda a testá -lo corretamente (modelar, testes de banco de dados e assim por diante).

O DAO é um serviço e, como um, poderíamos envolver nosso processo em uma classe bem fácil de manutenção.

O JPA reduz o número de linhas de códigos, mas, nada mais, as regras antigas ainda se aplicam.

JPA traz uma camada de repositório, mas seu Não é a nossa camada de repositório. No mesmo princípio, digamos que encapsulamos uma lógica que obtenha o lucro de algum processo. Pode ser que o encapsulamento seja simplesmente uma multiplicação para 0,1, mas ainda é digno de encapsular.

Por exemplo, digamos que tenho o próximo problema: por algum motivo estranho, posso inserir um novo cliente no banco de dados?. Onde devo começar a testar?. R: ClientDao, se existe, se não, então boa sorte em encontrar em outro lugar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top