[quote=sergiotaborda][quote=ravisantos]
O problema aqui é, onde entraria os metodos findAllByExample, no Repository ou nos Dao’s?
Como podem ver estou um pouco confuso com estes dos Patterns.
Se alguem puder esclarecer agradeço.
[/quote]
Vamos lá (de novo)
Repositorio : objeto responsável por encontrar instancias de entidades. Se ele é responsável por encontrar , os métodos find ficam com ele. Obvio, não ?
DAO : objecto responsável por acessar dados em fontes de tecnologia diversa. Ele isola a tecnologia de persistencia. Normalmente é um por entidade. (DAO genérico é uma aberração da natureza).
DomainStore : objecto responsável por toda a persistencia do dominio (o nome diz tudo). Ele utiliza DAO por baixo dos panos mas o cliente não os vê.
É um domainstore por dominio.
Um repositorio pode usar DAO, mas é mais natural utilizar DomainStore porque ambos se relacionam ao dominio.
Hibernate : implementação “comercial” de um DomainStore especializado em persistencia em banco de dados.
Se vc usa o hibernate você está dizendo que a persistencia apenas pode acontecer em banco de dados ( em traços largos, porque em tese o hibernate é expansivel a outras midias… mas não existe isso ainda).
O Repositorio tem aquele interface que vc chama de DAO. Com add, remove, e os finds. O repositorio base tem o findByID e os findAll() que são mais utilizados.
Um repositorio especifico para Cliente, por exemplo tem mais métodos find especificos de Cliente. Por exemplo findBySellRegion(Region r), findByNetRetail(Money minRetail) , etc … um report, por exemplo, é um método find do respositorio.
É facil implementar estes métodos ? Não. Vc precisa usar truques como Specification para a paginação e FastLaneReader para a leitura rápida sem consumir muitos recursos. Repositoriy é a melhor forma de modelar acesso a dados do ponto de vista do core de negocio. ( O padrão repositorio é velho. O Fowler que inventou antes do DDD existir. Repositorio não implica em DDD).
Bom, mas como implementar isso ?
Vamos ver com hibernate primeiro.
Para cada método vc delega ao hibernate de forma semelhantes ou qe já tem. Vc pode ter um HibernateAbstractRepository que implementa o básico do add , remove , etc… que é sempre igual. Além disso vc precisa de um método protegido findByCriteria(Criteria c). Este método é o coração da coisa toda. Um ClienteRepository irá implementar os seus finds especificos criando criterios do hibernate e mandar para aquele método. Isso é simples e é facil acrescentar novos métodos find. Se vc precisar de paginação , fastlane ou outras coisas, vc precisa incrementar o findByCriteria para ser o suficientemente poderoso para todos esses cenários. Um bom padrão para isso é criar uma interface padrão para a resposta ( que não seja um list). eu costumo usar algo como
public interface QueryResult<T> {
public T first();
public Collection<T> all()
public boolean isEmpty();
public int count();
public QueryResult subQuery(int first, int count);
}
Esta interface permite criar um relay entre a chamada ao método find do repositorio e a real execução da pesquisa. Permite que a pesquisa seja otimizada , pois um count() não precisa ser all().size() , pode ser um SELECT count FROM … e o subQuery é para permitir paginação sem ter que colocar isso no contrato do método find. Assim vc pode paginar qualquer resultado de qualquer método find.
moral da historia, um bom design OO ajuda muito.
Bom, blz. Vc tem o seus repositorios utilizando o hibernate. Mas e se quiser se livrar do hibernate e trocar por JPA (supondo que isso é possivel)?
Ai vc mantém o repositorio criandos critérios, mas agora, vc tem que implementar a API de critérios de forma independente do Hibernate e do JPA ou de qq outra coisa. Depois vc cria um RepositoryStrategy que contém as implementações reais de add, remove, findByCriteria. Todos os métodos do repositorio delegam à estratégia. E a estratégia delega ao mecanismo real do hibernate, jpa , etc… A estratégia é injetada no repistorio via construtor.
A estratégia irá traduzir o seu critério de pesquisa agnostico (que não depende da tecnologia subjacente) para um critério especifico ( do hibernate, do jpa ,etc…). A estratégia irá executar o mecanismo especifico e retornar os dados. É assim que vc isola a tecnologia de persistencia do repositorio em si.
Para o caso simples e cotidiano pode manter o hibernate atrelado ao repositorio e só abstrair o hibernate quando outro mecanismo aparecer/for necessário.
E o DAO ? O DAO vc esquece.
[/quote]
Olá Sérgio, depois dessa aula. Algumas duvidas ainda me restaram. Por exemplo este metodo findByCriteria retornaria o que ?
E essa interface quema implementaria, me interessei por essa interface mais ainda não sei como aplica-la na pratica. Sem querer pedir demais poderia dar um exemplo;
Obrigado!