Olá a todos!
Estou fazendo um projeto pessoal e gostaria da opinião de vocês a respeito da arquitetura utilizada. O sistema é sobre controle financeiro pessoal e consiste basicamente de CRUDs para entidades auxiliares(Conta, Tipo de Conta e Forma de Pagamento) e para a entidade principal(Lançamento). Essa última, além do CRUD, também tem buscas avançadas e relatórios. As tecnologias que estou usando: Maven, Spring, Jboss Seam, Hibernate
Segue abaixo o exemplo para o CRUD de Contas.
HibernateRepository.java(package common.infrasctructure)
public abstract class HibernateRepository<T, ID extends Serializable> extends HibernateDaoSupport {
//metodos padroes com implementacao usando hibernate..add, find's, update, remove
}
ContaRepository.java(package conta.domain)
public interface ContaRepository {
//metodos padroes..add, find's, update, remove
...
Conta findByDescricao(String descricao);
}
ContaRepositoryHibernate.java(package conta.infrastructure)
public class ContaRepositoryHibernate extends HibernateRepository<Conta, Integer>
implements ContaRepository {
//implementacao apenas dos metodos que nao estao em HibernateRepository
public Conta findByDescricao(String descricao) {
QuerySpecification query = new QuerySpecification()
.addRestriction(Restriction.equals("descricao", descricao));
List<Conta> res = findByListOfCriterion(Converter.convertToListOfHibernateCriterion(query));
if(res.size() == 0) {
return null;
}
return res.get(0);
}
}
*QuerySpecification. Faz parte de uma biblioteca que fiz para montar consultas em alto-nível. A classe Converter faz a conversão para um List de Criterion ou para SQL puro. O método findByListOfCriterion vem de HibernateRepository.
E na minha Action eu chamo por exemplo
..
@End
public void add() {
contaRepository.add(conta);
facesMessages.add("#{messages['label.conta.inserida']}");
conta = new Conta();
}
..
No Spring eu fiz os métodos do repository que não começam com “find” como Transacional.
Dúvida 1: Se eu precisasse por exemplo, antes de inserir a Conta, verificar se já existe uma conta com aquela descrição e, caso afirmativo, lançar uma exception. Eu poderia fazer esse check no add de ContaRepositoryHibernate ou o correto seria criar um service que faz a validação/inserção usando o repository e na minha action eu chamo o service ao invés de diretamente o Repository?Ou outro jeito?E no caso de usar o Service, mudaria no Spring para a Transação ser em cima do Service ao invés do Repository.
Falando agora sobre a entidade Lancamento, na parte de relatórios. Um relatório exemplo seria um que listasse todos os lançamentos de um período e no final mostrasse o total de entrada, saída e o saldo.
Dúvida 2: Eu preciso criar um Bean para representar a esturura desses dados, certo?Com um List de lancamentos, totalEntrada, totalSaida e Saldo. Qual seria a nomenclatura correta para esse tipo de Classe?RelatorioSimplesDeLancamentos.java seria o suficiente ou é interessante usar algum sufixo(DTO, VO…?). Em qual package o deixaria, junto com a entidade Lancamento em lancamento.domain?
Dúvida 3: Para montar esse relatório eu vou precisar buscar um List de lancamentos no BD e ir manipulando esses dados para preencher o RelatorioSimplesDeLancamentos.java. Isso eu posso fazer direto no Repository ou é interessante criar um Service que pede ao Repository os dados e então os manipula?
Qualquer sujestão será bem-vinda.
Desde já muito obrigado!
Luciano