Problema Hibernate - Coleções

8 respostas
Emerson_Mendes

Galera, sou iniciante em Hibernate e estou com um problema…
tenho um objeto Cliente e um objeto Telefone.

public class Cliente {
     private int id;
     private String nome;
     private String cnpj;
     private List<Telefone> telefone;

     // getters e setters

}

public class Telefone {
     private int id;
     private int ddd;
     private String numero;
     private Cliente cliente;

     // getters e setters

}

As duas classes estão relacionadas com @OneToMany e @ManyToOne certinho…
Sendo assim, se eu criar uma instancia de Cliente, popular o objeto e settar N telefones, quando persisto o cliente o Hibernate tb insere os telefones… até ai show de bola…

meu problema é quando vou editar o cliente… altero a lista de telefones… incluindo novos, excluido alguns e editando outros… o hibernate não persiste os telefones… ele só está inserindo os novos… mas os que eu limpei da coleção não foram apagados… :frowning:

Alguem sabe se da para persistir novamente, fazendo com que o Hibernate atualize a lista toda?!?!?!!?!!?

Vlwww galera…

flw

8 Respostas

Veneno

manda o codigo que persiste …

Emerson_Mendes

Segue código que realiza update…

public static void main(String[] args) {
	Session session = HibernateUtil.getSession();
	Transaction tx = session.beginTransaction();

                // Retrieve de um cliente cadastrado
	Cliente c = (Cliente)session.get(Cliente.class, 1);
		
	// Nova Lista de telefones. Lembrando que a lista atual tem 4 telefones cadastrados.
	List<Telefone> novaLista = new ArrayList<Telefone>();
		
	Telefone a = new Telefone();
	a.setNumero("123456789");

	Telefone b = new Telefone();
	b.setNumero("987654321");
		
	novaLista.add(a);
	novaLista.add(b);
		
	// Set da nova lista
	c.setTelefone(novaLista);
		
	session.update(c);
		
	tx.commit();
}

… ou seja… estou setando uma nova lista com 2 objetos telefone… a lista antiga tinha 4 objetos… eu queria que o hibernate considerace a lista nova…

Vlwwwwww

bland

Emerson,

Você disse uma coisa e está fazendo outra. O Hibernate não tem como adivinhar o que você deseja fazer, ele apenas realiza o que você MANDA ele realizar. Se você adiciona dois registros a uma lista, ele fará isso. Se você quer apagar, ele vai apagar. Agora ele não apagará sem que você mande, entende? Se você quer que ele desconsidere a antiga lista, então você terá de dar um “clear” na tabela antes de inserir os novos registros. Somente assim ele funcionará da maneira que deseja.

Abraço.

Veneno

Pelo que percebi vc ta criando uma nova lista …
tenta assim:

// Nova Lista de telefones. Lembrando que a lista atual tem 4 telefones cadastrados.       
    List<Telefone> novaLista = c.getTelefone();
Veneno

hum nao tinha entendido…
nao ta inserindo todos, os antigos e os novos ??
ou ta ??

H

O que acontece é que se você não especificar está operação deverá ser feita de forma automatica.

Na sua classe cliente coloque a seguinte anotação.

@OneToMany(cascade = { CascadeType.PERSIST , CascadeType.MERGE}) private Collection&lt;Telefone&gt; telefone;

Este mapeamento informa que quando for executando uma Inserção ou Alteração na entidade Cliente será feito também em telefone.

root_

Estou na mesma situaçao do Emerson…
fiz o cascateamento ( cascade = CascadeType.ALL ) e os dados antigos da coleçao ainda ficam…

Como faço para limpar a coleçao e setar os novos valores?

Ja tentei:

// somente o trecho q interessa.
cliente.getTelefonesList().clear();
cliente.setTelefonesList(novaLista);
clienteDAO.update(cliente);

Mais nao da certo… Alguma sujestao?

Lavieri

sim tem sugestão sim…

o problema é que vc precisa setar o relacionamento nos dois lados, esse é o problema de ter algo bidirecional

não basta fazer

cliente.getTelefonesList().clear();

cliente.setTelefonesList(novaLista);

clienteDAO.update(cliente);

isso só vai faer o provedor de persicencia operar assim

for(Telefone telefone : cliente.getTelefonesList()) update(telefone); }

ou seja… como vc não esta adicionando ao telefone o relacionamento dele com cliente não funfa

o correto seria

for(Telefone telefone : cliente.getTelefonesList()) telefone.setCliente(cliente); update(telefone); }

mas isso o provedor de persistencia não faz…

… portanto se quer relacionemento bi-direcional vc precisa esconder as coisas

esconda a lista real, retonra um lista read-only …
crie um método addTelefone(String numero) na classe cliente… e crie vc mesmo o telefone, sete o cliente do telefone como this …

para verificar como fazer um exemplo esta neste post => http://guj.com.br/posts/list/15/141017.java#761209
o tema do post é chave composta, mas no final eu abordo o relacionamento, e ai tem um exemplo de como proceder para a cascata funcionar bem

Criado 17 de outubro de 2007
Ultima resposta 16 de out. de 2009
Respostas 8
Participantes 6