Problemas para clonar objeto

2 respostas
S

Pessoal, to ficando maluco aqui já, meu problema é o seguinte: conforme esse tópico que eu abri (http://guj.com.br/posts/list/197498.java),

quando o usuário clicar editar, na verdade não quero editar e sim salvar um novo registro.

Não é uma questão de histórico, pra isso eu já uso o Hibernate Envers, e sim uma necessidade do sistema.

Já nem sei o que to fazendo de errado: se são os métodos equals() ou clone() que estão implementados de maneira errada, não sei se é o gerenciamento das transações (como uso JTA é automático) ou se eu não estou sabendo manipular os objetos, o fato é que isso:
pointConfig.setActive(false);
//entityManager.flush();
entityManager.merge(pointConfig);

entityManager.clear();

pointConfig.setPointConfigId(null);
pointConfigEdit = (PointConfig) pointConfig.clone();

entityManager.clear();

if(pointConfig == pointConfigEdit) {
	System.out.println("iguais");
} else {
	System.out.println("diferentes"); <==== ** E são diferentes mesmo!! **
}

pointConfigEdit.setActive(true);
entityManager.flush();
entityManager.persist(pointConfigEdit);
não funciona, por algum motivo o pointConfig.setActive(false); não funciona, acaba indo como true, já debuguei também e os id's dos objetos são realmente diferentes, já comparei os objetos (linha 15) e vi que são diferentes, o que posso estar fazendo de errado?

Outra coisa, se eu descomentar a linha 02, ele seta como false só que outros campos como formula, caso seja mudado, acaba atualizando!!!

Segue meu código:
ENTIDADE
public class PointConfig implements Serializable, Cloneable {

	private Integer pointConfigId;	
	private Point point;
	private String formula;
	private boolean active;
	
	// Construtor, Get's e Set's
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((getPointConfigId() == null) ? 0 : getPointConfigId().hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof PointConfig))
			return false;
		PointConfig other = (PointConfig) obj;
		if (getPointConfigId() == null) {
			if (other.getPointConfigId() != null)
				return false;
		} else if (!getPointConfigId().equals(other.getPointConfigId()))
			return false;
		return true;
	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		try {
			return super.clone();
		} catch (CloneNotSupportedException x) {
			throw new InternalError(x.toString());
		}		
	}
}
MB
@Begin(flushMode = FlushModeType.MANUAL)
public String editPointConfig() {	
	if(pointConfig.getPointConfigId() != null) {
		entityManager.refresh(pointConfig);		
	}		
	return "editPointConfig";
} 

@End
public String savePointConfig() throws CloneNotSupportedException {
	if (pointConfig.getPointConfigId() != null) {
					
		pointConfig.setActive(false);
		//entityManager.flush();
		entityManager.merge(pointConfig);
		
		entityManager.clear();
		
		pointConfig.setPointConfigId(null);
		pointConfigEdit = (PointConfig) pointConfig.clone();
		
		entityManager.clear();
		
		if(pointConfig == pointConfigEdit) {
			System.out.println("IGUAIS");
		} else {
			System.out.println("DIFERENTES");
		}
		
		pointConfigEdit.setActive(true);
		entityManager.flush();
		entityManager.persist(pointConfigEdit);		
	}
	listPoints();
	return "savePointConfig";		
}

Abraços!!!

2 Respostas

Paulo_Silveira

o clone provavelmente esta cloandno tambem algumas informacoes do proxy que o hibernate usa (ja que o metodo eh herdado pela proxy). Em vez de usar clone, crie um objetivo novo e na mao faca a brincadeira de obj.setX(obj.getX())

S

Paulo,

Acho que o problema não é a clonagem e sim eu ter que alterar o objeto original (active == false).

Na solução que voce sugeriu, aconteceria a mesma coisa, porque quando eu fizesse

objetoOriginal.setActive(false); em.merge(objetoOriginal);
Eu colocaria o objetoOriginal no contexto do JPA novamente, o tornando persistível, e acabaria atualizando os outros campos.

Se eu utilizasse o Hibernate, daria pra usar o evict() para tirar as instancias individuais do contexto de persistência, mas o JPA não possui tal método!!!

Eu acabei tendo que utilizar uma solução um pouco bizarra, fazendo update direto, atualizando todos para “active = false”, exceto o objetoClonado

em.createQuery("" + "update PointConfig pc set pc.active = false " + "where pc.point.pointId = :point " + "and pc.pointConfigId <> :pointConfigEdit ") .setParameter("point", pointConfigEdit.getPoint().getPointId()) .setParameter("pointConfigEdit", pointConfigEdit.getPointConfigId()) .executeUpdate();

Abraços!!

Criado 15 de março de 2010
Ultima resposta 15 de mar. de 2010
Respostas 2
Participantes 2