[Resolvido]Ajuda para replicar objetos com Hibernate

9 respostas
jv.nicocelli

Prezados, Bom dia!

Estou desenvolvendo uma aplicação web utilizando JSF com Hibernate para persistência e me deparei com uma situação que não consegui resolver.
Eu preciso replicar um objeto que tenho persistido no banco de dados para a mesma tabela do banco, ou seja, preciso fazer uma copia da linha e salvar as mesmas informações com a id diferente.

A classe session do Hibernate possui um método replicate( ) , porem , nenhum dos modos de replicação se adequa a o que eu preciso fazer.

Alguém pode me dar uma ideia de como posso fazer?

9 Respostas

drsmachado

1 - Qual estratégia de geração de ID você está usando?
Se for automática, terá problemas. Se for manual, nenhum.
É através do ID de uma entidade que o Hibernate “se acha” no meio de toda parafernalha.

jv.nicocelli

A forma de geração de ID é automática…

drsmachado

Neste caso, meu camarada, você está dizendo ao Hibernate que ele deve seguir os próprios padrões.
Isso significa que, sempre que ele identificar um objeto com um ID já definido, irá associar o mesmo à sua sessão.
Faça um teste.
Realize uma busca (pode ser com o método load mesmo), defina o ID da entidade como null e tente salvar.

jv.nicocelli

Desculpe a ignorância, mas como eu defino um int como null se o valor default de int é 0?

Eu testei da maneira abaixo:

Clie_010 clie_010 = (Clie_010)session.load(Clie_010.class, 1);
		
		int id = (Integer) null;
		clie_010.setId(id);
		clieDao.salvar(clie_010);

Porém dessa forma ocorre NullPointerException

drsmachado

nicocelli:
Desculpe a ignorância, mas como eu defino um int como null se o valor default de int é 0?

Eu testei da maneira abaixo:

Clie_010 clie_010 = (Clie_010)session.load(Clie_010.class, 1);
		
		int id = (Integer) null;
		clie_010.setId(id);
		clieDao.salvar(clie_010);

Porém dessa forma ocorre NullPointerException


Eis aqui mais um exemplo de problemas gerados quando usamos tipos primitivos em para um framework orientado a objetos fazer as coisas.
Se usasse Integer, poderia anular os valores.
Você vai precisar mudar a estratégia, informando valores que ainda não foram atribuídos ao ID, manualmente.

jv.nicocelli

Bom, nesse caso eu fiz código seguinte, continua dando erro.

Query q =  null;
		try {
			//Retorna o valor do próximo registro da tabela
			q = session.createQuery("select coalesce(MAX(c.id)+1,1) from "
					+ Clie_010.class.getName() + " c ");
			
			int id = (Integer) q.uniqueResult();
			//Busca o cliente com id = 1
			Clie_010 clie_010 = (Clie_010)session.load(Clie_010.class, 1);
			clie_010.setId(id);
			clieDao.salvar(clie_010);	
		} catch (HibernateException e) {
			e.printStackTrace();		
		}
		
	}

O hibernate está entendendo que eu quero alterar a ID do meu objeto e não que será um novo objeto.

Olha o que acontece: identifier of an instance of br.com.webtransp.model.cliente.Clie_010 was altered from 1 to 3

drsmachado

Vamos por partes.
1 - O hibernate usa um sistema de gerenciamento de sessões.
Você está na mesma sessão, o objeto ainda é conhecido do hibernate pelo identificador 1, logo, até que feche-se esta sessão e inicie outra, ele sempre será o 1.
Agora, após fechar a sessão corrente, alteraro id de 1 para 3 e tentar persistir, ele deve aceitar como um novo elemento.
Detalhe, não estou podendo testar no momento, o que estou dizendo é baseado no modelo do hibernate, logo, deve funcionar.

ErickRAR

Tente sem o load. Apenas com o setId e depois salvar.

jv.nicocelli

drsmachado:
Vamos por partes.
1 - O hibernate usa um sistema de gerenciamento de sessões.
Você está na mesma sessão, o objeto ainda é conhecido do hibernate pelo identificador 1, logo, até que feche-se esta sessão e inicie outra, ele sempre será o 1.
Agora, após fechar a sessão corrente, alteraro id de 1 para 3 e tentar persistir, ele deve aceitar como um novo elemento.
Detalhe, não estou podendo testar no momento, o que estou dizendo é baseado no modelo do hibernate, logo, deve funcionar.

drsmachado ,

É exatamente isso que você falou, eu fechei a sessão que recuperou o objeto do banco e salvei.

Dessa forma, resolvi o problema utilizando o método replicate mesmo, pois eu seto a ID com o identificador da próxima linha da tabela e não ocorre problema algum.

Obrigado pela grande ajuda.

Criado 3 de julho de 2012
Ultima resposta 3 de jul. de 2012
Respostas 9
Participantes 3