JPA removendo itens da base que nao deviram ser removidos

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?

Segue o mapeamento:


@Entity
@Table(name="tb_transportadora", schema="vendas")
@Validavel
public class Transportadora implements Serializable {
	
	
	@OneToMany(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.MERGE})
	@JoinTable(name="vendas.tb_transportadora_tb_contato",
	joinColumns={@JoinColumn(name="id_transportadora", referencedColumnName="id")}, 
	inverseJoinColumns={@JoinColumn(name="id_contato", referencedColumnName="id")})
	private List<Contato> listaContato = new ArrayList<Contato>();
	
	
}

Vlwww

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?

Vou testar!!!

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.

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.

[quote=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. [/quote]Como que você faz para relacionar esses objetos e ter o resultado esperado em um insert?

O relacionameto foi definido na @JoinColumn annotation, imaginei que se isso seria o suficiente.

[quote=Vini Fernandes]O relacionameto foi definido na @JoinColumn annotation, imaginei que se isso seria o suficiente.[/quote]Eu estou perguntando o seguinte:
como você faz para inserir no banco um objeto corretamente relacionado?

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.

[quote=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.[/quote]Sem código fica difícil ajudar.

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);

[quote=Vini Fernandes]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); [/quote]Esse é oq está dando erro, certo?

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);	
}

[quote=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.[/quote]Me mostra agora um código que você faça o insert com sucesso.

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.

Eu reaproveito o codigo para fazer insert/update.

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:

[quote=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); } [/quote]

E se estiver == null?

Espero que alguém te ajude.

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???

[quote=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??? [/quote]Tenho sistema aqui que usa unidirecional e nunca tive problema com isso.

Vou deixar outra pessoa aqui falar oq pode ser seu problema.