Mapeamento Oneroso

29/11/2009

Oi,

Boa noite.
Estou precisando de uma ajuda em Hibernate.

Tenho a relação de um para muitos entre departamento e empregados. Ela é implementada conforme abaixo: //Na classe Departamento    @OneToMany        @JoinColumn(name="id_empregado")        private Set<Empregado> empregados;   O problema é que toda vez que quero adicionar ou remover um empregado, o código fica como abaixo: departamento.getEmpregados().add(empregado);    departamento.getEmpregados().remove(empregado);    Ou seja, ele busca todos os empregados do departamento para adicionar ou remover apenas um.
Quando chamo getEmpregados() e depois adiciono um, mesmo no modo LAZY, ele manda um select.
Não faz sentido ter um select a mais, quando basta apenas um único insert ou delete. A medida que o banco vai crescendo, essa dupla e desnecessária operação se torna cada vez mais onerosa.

Sei que existe uma estratégia para contornar isto, mas não encontrei em foruns ou no livro "JPA com Hibernate". 

Obrigado
Leonardo

Leonardo

Curtidas 0

Respostas

Dyego Carmo

Dyego Carmo

29/11/2009

Bom , isto não é um defeito... é uma caracteristica :)

por que digo isto ? Porque é assim que "deveria-se" fazer quando voce programa orientado a objetos , porem no mundo REAL ( que é aquele que realmente vale) isso impacta em selects desnecessarios...


Pois bem... para o inserte tem uma solucao :)

Na sua entidade, neste seu SET, HOJE voce declara ele assim:

private Set<Empregado> empregados; 

declare assim:
private Set<Empregado> empregados = new LinkedHashSet<Empregado>(); 

Pois bem , assim na inclusao voce nao vai depender de dar um getEmpregados... voce vai criar um metodo nesta sua entidade:

public void addEmpregado(Empregado e) {
    empregados.add(empregado);
    e.setDepartamento(this);
}


Pois bem , agora para adicionar um novo empregado chame diretamente o metodo addEmpregado... e isso vai resultar em algo que não vai dar select atoa.

Ja para o caso do DELETE , infelizmente , se voce pretende remover desta forma (recuperando o departamento e ai removendo o empregado) nao existe outra forma a nao ser o hibernate dar o tal "select"... e por que? Simples... o Hibernate transforma banco relacional em objetos , e para remover um objeto de ujm SET , este objeto deve estar dentro do set , nao é mesmo ?

Como resolve-se isso ? Simples. no seu DAO crie um metodo...

public void deletaEmpregado(int idEmpregado) {
    // RODE O SEGUINTE JPASQL , para tal recupere a sessao no seu dao e rode ele
    "DELETE FROM Empregado enpre where enpre.Id = "+idEmpregado;

}


este metodo nao vai fazer o tal select , e vai funcionar perfeitamente...



Valeu !

GOSTEI 0
Dyego Carmo

Dyego Carmo

29/11/2009

Bom dia !

Respondida sua duvida ?
GOSTEI 0
Leonardo

Leonardo

29/11/2009

Diego,

Resolveu sim.
Obrigado.

Abs,
GOSTEI 0
POSTAR