[RESOLVIDO] Hibernate: Comportamento estranho - Relacionamento MxN

3 respostas
mvlaran

Pessoall,

Nuns testes com o hibernate, ao remover uma entidade que aparece em 3 linhas de uma tabela intermediaria, ao invés de ele remover as 3 linhas referentes à esta entidade, ele removeu TUDO e inseriu novamente as linhas referentes às entidades que “sobraram”. :shock:

Pra uma tabela com 10 linhas, tudo bem, agora imagine uma tabela intermediária com 2.000.000 de registros?? ele removeria 2.000.000 e depois iria inserir mais 1.999.997 registros novamente?

o.O

Alguém tem idéia de por que isso pode estar ocorrendo? Quais informações precisam para me ajudar?

Obrigado!

3 Respostas

R

Teria como vc mandar mais informações. Eu não entendi o problema.
Mande tb algumas classes anotadas com @Entity que vc criou.

[]'s

mvlaran

Então... Fiz um teste assim:

Entidade EQUIPE:
// imports aqui...

@Entity
public class Equipe {

	@Id
	private int equipe;

	private String nome;

	@OneToOne
	private TipoEquipe tipoEquipe;

	@ManyToMany
	private List<Pessoa> pessoas = new ArrayList<Pessoa>();

	// getters e setters aqui...

}
Entidade TIPOEQUIPE:
// imports aqui...

@Entity
public class TipoEquipe {

	@Id
	private int tipoEquipe;

	private String nomeTipoEquipe;

	// getters e setters aqui...

}
Entidade PESSOA:
// imports aqui...

@Entity
public class Pessoa {

	@Id
	private int id;

	private String nome;

	@ManyToMany(mappedBy = "pessoas")
	private List<Equipe> equipes;

	// getters e setters aqui...

}
O Hibernate gerou o seguinte script SQL:
drop table Equipe cascade constraints

    drop table Equipe_Pessoa cascade constraints

    drop table Pessoa cascade constraints

    drop table TipoEquipe cascade constraints

    create table Equipe (
        equipe number(10,0) not null,
        nome varchar2(255 char),
        tipoEquipe_tipoEquipe number(10,0),
        primary key (equipe)
    )

    create table Equipe_Pessoa (
        equipes_equipe number(10,0) not null,
        pessoas_id number(10,0) not null
    )

    create table Pessoa (
        id number(10,0) not null,
        nome varchar2(255 char),
        primary key (id)
    )

    create table TipoEquipe (
        tipoEquipe number(10,0) not null,
        nomeTipoEquipe varchar2(255 char),
        primary key (tipoEquipe)
    )

    alter table Equipe 
        add constraint FK7C2D8A55ACA0E820 
        foreign key (tipoEquipe_tipoEquipe) 
        references TipoEquipe

    alter table Equipe_Pessoa 
        add constraint FKF6E014F11DC9DE83 
        foreign key (equipes_equipe) 
        references Equipe

    alter table Equipe_Pessoa 
        add constraint FKF6E014F167BB8FCD 
        foreign key (pessoas_id) 
        references Pessoa
O banco estava vazio, então adicionei TipoEquipes, Equipes e Pessoas:
//...
	t1.setNomeEquipe("Teste TipoEquipe1");
	t1.setTipoEquipe(1);
	//t2...
	//...

	e1.setEquipe(1);
	e1.setNome("Teste Equipe 1");
	e1.setTipoEquipe(t1);
	//e2, e3...
	//...

	p1.setNome("Teste P1");
	p1.setId(1);
	//p2, p3, p4, p5, p6, p7...
	//...
De forma tal que obtivesse situação que atendesse este diagrama:

[IMG]http://i757.photobucket.com/albums/xx212/mvlaran/venn.gif[/IMG]

Então, a tabela intermediaria ficou assim:
EQUIPES_EQUIPE	PESSOAS_ID
	1				1
	1			 	2
	1			 	3
	1			 	7
	2			 	3
	2			 	4
	2			 	5
	2			 	7
	3			 	1
	3			 	5
	3			 	6
	3			 	7
O problema que eu encontrei é ao remover a pessoa com ID 7. Veja que ela está nas 3 equipes, e corretamente aparece em 3 linhas tabela intermediária, fazendo a correspondência, dela com as 3 equipes. O código para remove-la é esse:
//...
	Dao<Pessoa> PessoaDao = new Dao<Pessoa>(session, Pessoa.class);

	Pessoa p = PessoaDao.load(7);

	Transaction tx = session.beginTransaction();

	// tirar a pessoa das equipes para remover
	p.getEquipes().get(0).getPessoas().remove(p);
	p.getEquipes().get(1).getPessoas().remove(p);
	p.getEquipes().get(2).getPessoas().remove(p);

	// bloco try catch...
	PessoaDao.delete(p);
	tx.commit();
	//...
Ao executar isto, o Hibernate faz tudo que precisa, e para deletar, além de deletar a linha referente à pessoa na tabela de pessoa, ele devereia apenas deletar 3 linhas na tabela intermediária. Só que ao invés disso ele faz:
Hibernate: 
    delete 
    from
        Equipe_Pessoa 
    where
        equipes_equipe=?
Hibernate: 
    insert 
    into
        Equipe_Pessoa
        (equipes_equipe, pessoas_id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Equipe_Pessoa
        (equipes_equipe, pessoas_id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Equipe_Pessoa
        (equipes_equipe, pessoas_id) 
    values
        (?, ?)
Hibernate: 
    delete 
    from
        Equipe_Pessoa 
    where
        equipes_equipe=?
Hibernate: 
    insert 
    into
        Equipe_Pessoa
        (equipes_equipe, pessoas_id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Equipe_Pessoa
        (equipes_equipe, pessoas_id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Equipe_Pessoa
        (equipes_equipe, pessoas_id) 
    values
        (?, ?)
Hibernate: 
    delete 
    from
        Equipe_Pessoa 
    where
        equipes_equipe=?
Hibernate: 
    insert 
    into
        Equipe_Pessoa
        (equipes_equipe, pessoas_id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Equipe_Pessoa
        (equipes_equipe, pessoas_id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Equipe_Pessoa
        (equipes_equipe, pessoas_id) 
    values
        (?, ?)
Hibernate: 
    delete 
    from
        Pessoa 
    where
        id=?
Fiz até um trigger no bd (Oracle) e ele de fato insere além de deletar. Veja que deletar pessoa ele faz direitinho. Mas na tabela intermediária ele está inserindo. O mais estranho é que após esta operação a tabela intermediária fica correta:
EQUIPES_EQUIPE	PESSOAS_ID
	1				1
	1			 	2
	1			 	3
	2			 	3
	2			 	4
	2			 	5
	3			 	1
	3			 	5
	3			 	6
mas não consigo entender o por que ele faz isso.

Como havia dito, pra uma tabelinha com 12 registros, isso é "peanuts" mas imagina se eu tivesse 2.000.000 e removesse 3? ele iria inserir novamente 1.999.997??? :shock:

Onde será que estou errando?

Abração!

mvlaran

Problema resolvido!

Usei SET ao invés de LIST! :shock:

Dêem uma olhada aqui e aqui!!!

Agora funciona 8)

Criado 29 de julho de 2009
Ultima resposta 5 de ago. de 2009
Respostas 3
Participantes 2