Olá Diego.
Acho que o repository não deve habitar o meu domínio, exceto se eu precisar executar alguma regra de negócio específica que implica alguma consulta na minha base.
Porque, querendo ou não, o repository na prática, ele não só traz o que “preciso” mas também contém toda a responsabilidade de conectividade com banco, por exemplo, montagem de query e tal, e acho que ao crescer o projeto vai bagunçar um pouco o meu domínio…
veja abaixo um exemplo prático, onde preciso cadastrar um usuário com email único, ai antes valido o email dele, se está formatado e se já existe um email cadastrado na base, se for td OK eu peço ao dao genérico (meu repository) para persistir:
OBS: esse exemplo usa VRaptor e Hibernate, mas qualquer dúvida posta aqui:
@Resource
public class UserController {
private final Result result;
private final UserDao dao;
private final EmailValidator emailValidator;
public UserController(Result result, UserDao dao, EmailValidator emailValidator) {
this.result = result;
this.dao = dao;
this.emailValidator = emailValidator;
}
@Post
public void create(User user) {
// se a validação do "register" estiver OK ele chama o dao para salvar, do contrário não faz nada o.O
if (user.register(dao, emailValidator)) {
dao.save(user);
result.include("msg", "Usuario salvo com sucesso");
}
}
}
@Entity
public class User extends EntityModelAb {
@Id
@GeneratedValue
private Long id;
private String email;
@Overread
public Long getId() {
return this.id;
}
public String getEmail() {
return this.email;
}
// regra de negócio
public boolean register(UserDao dao, EmaiLValidator emailValidator) {
return emailValidator.validate(this.email) && dao.isUniqueEmail(this.email));
}
}
@Component
public class UserDao {
private final Repository<User> repository;
public UserDao(Repository<User> repository) {
this.repository = repository;
}
public boolean isUniqueEmail(String email) {
Query query = this.repository.getQuery("select us.email from user us where :email = email");
query.setParameter("email", email);
return (query.getResult() == null || query.getResult().isEmpty()) ? true: false;
}
}
public interface Repository<T> {
// CRUD methods
Query getQuery(String queryStr);
}
@Component
public class GenericDao<? extends EntityModelAb> implements Repository<T> {
// JPA, Hibernate, Objectfy, ...
}
@MappedSuperClass
public abstract class EntityModelAb {
public abstract Long getId();
}
espero ter ajudado.
sugiro que faça esse mesmo questionamento no www.tectura.com.br pois la o foco maior é arquitetura, daí mais gente pode entrar na discussão!
Se postar la me avisa que vou postar esse mesmo tópico la, afinal tbm quero participar dessa discussão, que é mto interessante, rs
abraço!