JPA - Cascade.REMOVE não funciona

17 respostas
java
S

Eu tenho uma tabela chamada “Empresa” que está relacionada a tabela “Usuario” e Empresa é dona do relacionamento.

No mapeamento da tabela empresa tenho o seguinte código:

@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "usuarioId")
private List<Usuario> usuarioList;

Se eu criar a empresa e o usuario e depois tentar excluir a empresa recebo uma violate constraint exception, mas isso não deveria acionar a cascata???

Mas curiosamente se eu fechar e abrir a aplicação novamente consigo excluir normalmente em cascata. Após isso fiz vários testes e a unica coisa que resolveu via código era criando um novo EntityManagerFactory para cada delete() que eu fizer… Mas isso é uma bela de uma gambiarra que consome muitos recursos. Qual é maneira certa de fazer esse delete sem ter que criar um novo EntityManagerFactory?

17 Respostas

L

Qual a constraint que foi violada?

S

Ela se chama “FK_REFERENCE_2” mas ela na verdade é o unico relacionamento da tabela “Empresa” que liga o campo “empresaId” da tabela “Empresa”, no campo “empresaId” da tabela “Usuário”

L

Se dentro do usuário possui a empresa em que o mesmo está, então esse mapeamento está errado. Deveria ser:

@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "empresa")
private List<Usuario> usuarioList;
S
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "empresaId") private List usuarioList;

Falha minha, é que eu tentei de tudo acabei esquecendo assim XD… Alterei o código como acima e fiz o teste novamente, ainda assim só consigo excluir em cascata se eu fechar e abrir novamente a aplicação (o que tambem cria um novo EntityManagerFactory).

L

Na classe Usuário, a empresa está mapeada como?

S
@JoinColumn(name = "EMPRESA_ID", referencedColumnName = "EMPRESA_ID", insertable = false, updatable = false) @ManyToOne(optional = false) private Empresa empresaId;

Assim.

L

Porque insertable e updatable estão como false? Nâo deveria ser true?

S

Essa parte de código foi gerada automaticamente pelo Netbeans então nem ousei a modificar, e eu realmente nem sei pra que ele funciona, mas acredito que seja para que eu não consiga criar ou alterar o FK sem ter o objeto em questão persistido, mas vou tentar setando eles para true para ver se rola.

L

insertable:

Whether the column is included in SQL INSERT statements generated by the persistence provider.

fonte: JoinColumn Docs

S

Achei um caso parecido com o meu no stackOverFlow onde o cara tinha as tabelas Empregado, Patrao, e endereço, tanto o empregado quanto o patrao usavam a tabela endereço, e ao tentar excluir o empregado que tinha cascata pro endereco ele recebia a exception porque o patrao tambem usava essa tabela… Eu tenho algo parecido porque tenho a tabela usuario que tambem é usado pela tabela pessoa, e até ai tudo bem, mas porque ele faz o que eu quero quando uso outro entityManagerFactory (ou reinicio a aplicação)? Isso não deveria funcionar de maneira alguma, ou funcionar para todos os casos…

L

Hmmm, ai complica. Realmente bem estranho :confused:

L

Uma pergunta. Usuário é uma especialização de pessoa no seu banco?

S

É sim, Um usuário é criado quando eu ligo uma pessoa a uma empresa, é como uma relação de “muitos para muitos” entre empresa e pessoa. Por isso eu quero apagar o usuário e manter a pessoa quando excluo uma empresa.

L

Deveria excluir de boa, pois a chave do usuário não existe na pessoa. Acho que você poderia mostrar um pouco mais de código pra gente tentar entender o que está acontecendo.

S

O pior é isso… Eu consigo exatamente como deveria, mas só depois de reiniciar a aplicação, ou usar um EntityManagerFactory diferente…

É como se a Sessão em que eu criei os dois objetos ignorasse o Cascade, mas se ela não criou tais objetos ela passase a respeitar.

L

Se você pegar o SQL que é gerado pela JPA (antes da exceção) e executar diretamente no banco, o registro é excluído?

S

Está falando sobre um comando direto no banco? Não funciona porque no banco os cascades são restricts. Ou seja, se tiver filho restringe de deletar o pai.

Criado 15 de julho de 2016
Ultima resposta 15 de jul. de 2016
Respostas 17
Participantes 2