Cara, uma coisa é o conceito e a utilidade do repositorio. Outra coisa é ORM.
Misturar os dois dá merda.
O problema é que @manyToOne resolve em certas circusntâncias. Como já foi dito : se usar hibernate é tudo uma maravilha, mas se usar JDBC é um pesadelo. Mas Hibernate e JDBC são tecnologias de persistencia.
um repositorio (repositorio : onde vc coloca as coisas e depois pega de volta) não tem nada a ver com persistencia.
(persistir: manter por muito tempo)
Já existiram vários topicos sobre isto , e eu digo sempre a mesma coisa, então não vou me repetir. A questão é :
-
Entender o papel do Repositorio. Entender que o repositorio serve escatamente para não existirem ActiveRecords. Entender que o repositorio é tão ou mais consciente das relações entre as entidades que a entidades elas mesmas.
-
Entender que Repositorio é diferente de DAO. Eu sei que é dificil , mas ao menos tentem.
Repositorio : prover acesso centralizado ao conjunto de instancias de uma entidade.
DAO: prover acesso padronizado a N diferentes tencologias de persitencia cujas API não são equivalentes. -
Entender que se ( atenção ao SE) o sistema necessita de persistência então terá que haver um mapeamento entre o repositorio ( instancias em memoria) e o banco ( instancias persistidas).
3.a) O repositorio deve funcionar da mesma forma para qualquer sistema de persistencia pois ele não dependente disso.
Exemplo de repositorio com persistencia
class RepositorioTurma {
PersistenceAgent agent;
RepositorioAluno repAlunos;
public void add (Turma turma){
agent.insertOrUpdate(turma);
for (Aluno a : turma){
repAlunos.add(a);
}
}
}
Mais uma vez não chamei nada de DAO para que seja claro o papel de cada objeto.
Agora vc diz assim:
- “Mas porque colocar mais uma camada se posso chamar o agente de peristencia directamente ?”
O ponto é: Vc pode mas vc não quer. Se vc quer, vc não entender para que serve o repositorio.
- “Porque não implementar um repositorio generico?”
Vc pode implementar generico, mas o dominio deve ter acesso como se fosse individual
Mas é licito fazer algo como
E usar um mecanismo de injeção/fabrica. O ponto é que se eu pedir o repositorio de TipoDeProduto e eu não especificar qual implmentação quero, o metodo retorna uma implementação generica. Mas se eu definir um classe de implementação especifica, deve ser essa a retornada. O objetivo do repositorio é ter métodos especificos/especiais de busca que sejam directamente acoplados às regras de negocio.
Essa é uma grande diferença do DAO onde esses métodos devem ser fracamente acoplados às regras de negocio. Em DAO vc usa um criteria. No repositorio vc cria uma logica de negocio.
Um outro exemplo simples de como DAO e Repositorio são difernetes.
(sintaxe simplificada)
RepositorioAccountTransaction{
public void addAccountTransaction(AccountTransaction t ){
RecordMapper mapper = new RelectionMapper();
mapper.exclude( new MoneyFieldFilter() ); // esclui campos to tipo Money
Record t_rec = mapper.map(t);
Money value = t.value;
t_rec.setAmount(value.getAmount());
persistenceAgent.insertOrUpdate(t_rec);
RepositoryAccount.add(t.from);
RepositoryAccount.add(t.to);
}
public List<Transactions> getTransactions(Date date){
RecordQuery query = "from transaction where date = " + date; // simbolico
List<Record> records = persistenceAgent.execute(query);
List <Transactions> res = new ...
Currency c = Currency.newInstance("BRL"); // poderia ler de tabela
for (Record r : records) {
t = mapper.unMap(r);
t.value = new Money ( r.getAmount() , c);
res.add(t);
}
return res;
}
}
}
Pode até haver um forma de setar Money com uma Currency usando Hibernate. Esse não é o ponto.
O ponto é que o repositorio sabe , onde e como encontrar as coisas e produzir objetos de dominio corretamente.
Ele sabe regras de dominio. DAOs não devem saver regras de dominio.
Não sei mais o que dizer…