JPA removendo itens da base que nao deviram ser removidos
19 respostas
Vini_Fernandes
Caras, tem uma Transporada que contem uma lista de Contato. Para incluir um novo Contato a Transportadora eu adiciono esse novo contato a listaContato, porem ao efetuar o merge para atualizar os dados da Transpordora o novo contato eh adicionado, mas os outros contatos sao removidos da lista. Entenderia esse comportamento se eu carregasse todos os contatos, e depois removesse os contatos que nao interessassem e realizasse um merge no final. Esse comportamento eu entendo, mas nao eh o cenario. Alguem tem alguma ideia?
Se ao invés de fazer pessoa.getCarros.add(new Carro());
Você fizer pessoa.setCarros(carros);
O jpa eliminará a lista antiga. É isso mesmo que você queria saber?
Vini_Fernandes
Vou testar!!!
Vini_Fernandes
Entao, o problema agora eh outro. Tenho uma join_table que relaciona contato e tranportadora, sendo assim, essa operacao que voce sugeriu inlcui um registro na tb_transportadora, um retgistro na tb_contato, mas nao eh incluido o novo registro de tabela de relacionamento tb_transportadora_contato.
Hebert_Coelho
Vini_Fernandes
O que eu tenho eh um relacionamento de “composicao” entre transportadora e contato, alem disso eh um relacionamento unidirecional, ou seja, atraves da transportadora eu recupero seus contatos, pois em meu modelo nao tem sentido uma navegacao de um contato para uma transportadora.
Hebert_Coelho
Vini Fernandes:
O que eu tenho eh um relacionamento de “composicao” entre transportadora e contato, alem disso eh um relacionamento unidirecional, ou seja, atraves da transportadora eu recupero seus contatos, pois em meu modelo nao tem sentido uma navegacao de um contato para uma transportadora.
Como que você faz para relacionar esses objetos e ter o resultado esperado em um insert?
Vini_Fernandes
O relacionameto foi definido na @JoinColumn annotation, imaginei que se isso seria o suficiente.
Hebert_Coelho
Vini Fernandes:
O relacionameto foi definido na @JoinColumn annotation, imaginei que se isso seria o suficiente.
Eu estou perguntando o seguinte:
como você faz para inserir no banco um objeto corretamente relacionado?
Vini_Fernandes
Para nao cometer violacao de “constraints” eh necessario, primeiramente, criar um contato, e posteriormente, efetuar o vinculo na join table utilizando os id´s (chaves primarias) da tabelas de transportadora e de contatos. Imaginei que o mapeamento, mesmo que sendo unidirecional, do jeito que foi feito garantisse esse vinclulo.
Hebert_Coelho
Vini Fernandes:
Para nao cometer violacao de “constraints” eh necessario, primeiramente, criar um contato, e posteriormente, efetuar o vinculo na join table utilizando os id´s (chaves primarias) da tabelas de transportadora e de contatos. Imaginei que o mapeamento, mesmo que sendo unidirecional, do jeito que foi feito garantisse esse vinclulo.
Sem código fica difícil ajudar.
Vini_Fernandes
Segue o bloco de codigo responsavel pela a inclusao da transportadora com seus contatos em “cascade”
Segue o bloco de codigo responsavel pela a inclusao da transportadora com seus contatos em “cascade”
Logradouro logradouro = transportadora.getLogradouro();
if (logradouro != null) {
Endereco endereco = this.cepService.pesquisarByCep(logradouro.getCep());
if (endereco == null) {
endereco = this.entityManager.merge(logradouro.recuperarEndereco());
}
logradouro.addEndereco(endereco);
}
//essa eh a linha do merge
return this.entityManager.merge(transportadora);
Esse é oq está dando erro, certo?
Vini_Fernandes
Exato! Note que nesse ponto utilizo o mesmo tipo de cascade para inclusao de logradouro, mas ao efetuar o merge dos contatos tenho o problema. Estou adicionando os contatos na lista do mesmo modo que voce sugeriu anteriormente. Veja:
Exato! Note que nesse ponto utilizo o mesmo tipo de cascade para inclusao de logradouro, mas ao efetuar o merge dos contatos tenho o problema. Estou adicionando os contatos na lista do mesmo modo que voce sugeriu anteriormente.
Me mostra agora um código que você faça o insert com sucesso.
Vini_Fernandes
Tanto o insert quanto o update utilizam o mesmo codigo. Se uma transportadora eh novo (ID = null), o merge se encarrega de gerar um ID para ela e seus contatos. Ja quando uma transportadora esta “detached” (ID = 10, por exemplo) o merge se encarrega de inclui-la na unidade de persistencia. Por isso eu utilizo o mesmo codigo para ambas as situacoes.
Vini_Fernandes
Eu reaproveito o codigo para fazer insert/update.
Hebert_Coelho
Cara, eu realmente não entendi seu código. vou deixar para outra pessoa te ajudar.
Você falou:
mas no código que você mostrou, eu não vi quem poderia estar salvando isso.
Você também disse:
Vini Fernandes:
Exato! Note que nesse ponto utilizo o mesmo tipo de cascade para inclusao de logradouro, mas ao efetuar o merge dos contatos tenho o problema. Estou adicionando os contatos na lista do mesmo modo que voce sugeriu anteriormente. Veja:
if (listaContato != null && !listaContato.isEmpty()) {
transportadora.addContato(listaContato);
}
E se estiver == null?
Espero que alguém te ajude.
Vini_Fernandes
A minha ideia era de cascatear todas as acoes efetuadas em uma transportadora para seus contatos, apenas isso. Mas o que voce alteraria no mapeamento???
Hebert_Coelho
Vini Fernandes:
A minha ideia era de cascatear todas as acoes efetuadas em uma transportadora para seus contatos, apenas isso. Mas o que voce alteraria no mapeamento???
Tenho sistema aqui que usa unidirecional e nunca tive problema com isso.
Vou deixar outra pessoa aqui falar oq pode ser seu problema.