[RESOLVIDO] Hibernate: Comportamento estranho - Relacionamento MxN

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!

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

[]'s

Então… Fiz um teste assim:

Entidade EQUIPE:[code]
// 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...

}[/code]Entidade TIPOEQUIPE:

[code]
// imports aqui…

@Entity
public class TipoEquipe {

@Id
private int tipoEquipe;

private String nomeTipoEquipe;

// getters e setters aqui...

}[/code]Entidade PESSOA:

[code]
// imports aqui…

@Entity
public class Pessoa {

@Id
private int id;

private String nome;

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

// getters e setters aqui...

}[/code]O Hibernate gerou o seguinte script SQL:

[code] 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[/code]O banco estava vazio, então adicionei TipoEquipes, Equipes e Pessoas:

[code]
//…
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...
//...[/code]De forma tal que obtivesse situação que atendesse este diagrama:

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 7O 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:

[code]
//…
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();
//...[/code]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 6mas 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!

Problema resolvido!

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

Dêem uma olhada aqui e aqui!!!

Agora funciona 8)