Pessoal, to precisando fazer algo bem simples, mas do jeito que fiz não deu certo.
Na minha aplicação, quando o usuário clicar editar, na verdade não quero editar e sim salvar um novo registro.
Ex: tenho um cadastro de Ponto e outro de PontoConfig (um pra muitos), quando alterar um PontoConfig eu mantenho aquelas informações no banco e salvo uma nova (já com as alterações), tenho que fazer isso pra manter um histórico de alterações.
O que fiz? Instanciei um novo objeto e setei nele as informações do outro objeto, ele cria um novo registro, mas o antigo também está sendo alterado, segue o código:
@Begin
public String configPoint() {	
	if(pointConfig.getPointConfigId() != null) {
		pointConfigEdit = new PointConfig(); // instancio um novo objeto (pointConfigEdit) para guardar as informações da alteração
		entityManager.refresh(pointConfig); // recupero o objeto pointConfig
	}	
	return "configPoint";
}
@End
public String savePointConfig() {
	if (pointConfig.getPointConfigId() != null) {
		/* seto em pointConfigEdit as informações de pointConfig */
		pointConfigEdit.setClient(pointConfig.getClient());
		pointConfigEdit.setEquipmentInstallation(pointConfig.getEquipmentInstallation());
		pointConfigEdit.setFormula(pointConfig.getFormula());
		pointConfigEdit.setPoint(point);
		pointConfigEdit.setRegister(pointConfig.getRegister());
		pointConfigEdit.setSensor(pointConfig.getSensor());
		pointConfigEdit.setTeam(pointConfig.getTeam());
		pointConfigEdit.setConfigAlert(pointConfig.getConfigAlert());
		
		entityManager.persist(pointConfigEdit); // persisto apenas pointConfigEdit, mas no banco tá alterando também o pointConfig!!! 
	}
	listPoints();
	return "savePointConfig";		
}
Porque tá dando um merge no pointConfig?
O que tenho que fazer para isso dar certo?
Obrigado!
         
        
          
        
           
           
           
         
         
            
            
          
       
      
        
        
          Provavelmente por causa do seu mapeamento.
PointConfigEdit está como “pai” na relação. Assim quando é editado salva as informações do pointConfig
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          [quote=Graciano]Provavelmente por causa do seu mapeamento.
PointConfigEdit está como “pai” na relação. Assim quando é editado salva as informações do pointConfig[/quote]
E aí Graciano, na verdade PointConfigEdit é uma nova instancia de PointConfig.
Eu recupero pointConfig através do método refresh, instancio um novo objeto (pointConfigEdit), seto nesse novo objeto as infos de pointConfig e dou um persist no novo objeto.
Provavelmente não seja a maneira correta a se fazer, sabe como eu poderia fazer isso (criar novo objeto ao invés de editar)?
Obrigado
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          [quote=samerjamal]Pessoal, to precisando fazer algo bem simples, mas do jeito que fiz não deu certo.
Na minha aplicação, quando o usuário clicar editar, na verdade não quero editar e sim salvar um novo registro.
Ex: tenho um cadastro de Ponto e outro de PontoConfig (um pra muitos), quando alterar um PontoConfig eu mantenho aquelas informações no banco e salvo uma nova (já com as alterações), tenho que fazer isso pra manter um histórico de alterações.
![/quote]
Não mantenha o historico na propria tabela. Crie uma tabela de historico. Manipule apenas o mais recente.
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          [quote=sergiotaborda][quote=samerjamal]Pessoal, to precisando fazer algo bem simples, mas do jeito que fiz não deu certo.
Na minha aplicação, quando o usuário clicar editar, na verdade não quero editar e sim salvar um novo registro.
Ex: tenho um cadastro de Ponto e outro de PontoConfig (um pra muitos), quando alterar um PontoConfig eu mantenho aquelas informações no banco e salvo uma nova (já com as alterações), tenho que fazer isso pra manter um histórico de alterações.
![/quote]
Não mantenha o historico na propria tabela. Crie uma tabela de historico. Manipule apenas o mais recente.[/quote]
Mas essa não é uma decisão minha, é uma especificação  
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          será que o método clone() resolveria meu problema?
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Pessoal, tentei com o método clone(), pelo debug vi que ele tá copiando o objeto em outra instância realmente, só que deu o seguinte erro:
javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: org.domain.infralogjava.entity.PointConfig
Segue o código:
@Begin
public String configPoint() {
	
	if(pointConfig.getPointConfigId() != null) {			
		entityManager.refresh(pointConfig);			
	}	
	return "configPoint";
}
@End
public String savePointConfig() throws CloneNotSupportedException {
	if (pointConfig.getPointConfigId() != null) {
		pointConfigEdit = (PointConfig) pointConfig.clone();
		entityManager.persist(pointConfigEdit);
	}
	listPoints();
	return "savePointConfig";		
}
Alguém tem idéia do porque isso ocorre?
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          sete o campo pointConfigId para null.
Quando o campo @Id do Hibernate não for null ele vai acreditar que o objeto não é novo.
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Felagund, eu fiz isso e não deu também, setei antes de clonar, segue o erro:
org.hibernate.HibernateException: identifier of an instance of org.domain.infralogjava.entity.PointConfig was altered from 27 to null
Código:
@Begin
public String configPoint() {
	if(pointConfig.getPointConfigId() != null) {			
		entityManager.refresh(pointConfig);			
	}	
	return "configPoint";
}
@End
public String savePointConfig() throws CloneNotSupportedException {
	if (pointConfig.getPointConfigId() != null) {
		
		pointConfig.setPointConfigId(null);
		pointConfigEdit = (PointConfig) pointConfig.clone();
		
		entityManager.persist(pointConfigEdit);
	}
	listPoints();
	return "savePointConfig";		
}
Vi no debug que está copiando corretamente, e o pointConfigId do pointConfigEdit é criado como null, mas o clone não persiste!!
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Ta, então assim cara, esse problema ocorre pq a classe da no EntityManager já, ele acredita que vc esta modificando uma classe ja salva, e ela ja esta no contexto do EM.
Qual a utilidade do refresh na entidade? existem mesmo a necessidde de sincronizar a entidade com o banco antes de salvar?
Experimente remover esse refresh e executar o save.
att
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          [quote=Felagund]Ta, então assim cara, esse problema ocorre pq a classe da no EntityManager já, ele acredita que vc esta modificando uma classe ja salva, e ela ja esta no contexto do EM.
Qual a utilidade do refresh na entidade? existem mesmo a necessidde de sincronizar a entidade com o banco antes de salvar?
Experimente remover esse refresh e executar o save.
att[/quote]
Então velho, eu tenho que dar refresh sim, pq é uma edição, preciso recuperar as informações.
Uma vez que as recupero, quero copiá-las para uma nova instancia e salvá-las, pois não quero dar update nas informações antigas (quero mante-las inalteradas) e sim salvar as alterações em um novo registro.
Não sei se conseguiu entender e nem sei se é a maneira correta de se fazer isso.
Abraços!
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          Pra historico, use o ENVERS do hibernate.
Mas, se realmente quer fazer isso na mao, de um clear no entitymanager e depois sete a PK para null/zero
         
        
        
           
           
           
         
         
            
            
          
       
      
        
        
          [quote=Paulo Silveira]Pra historico, use o ENVERS do hibernate.
Mas, se realmente quer fazer isso na mao, de um clear no entitymanager e depois sete a PK para null/zero[/quote]
Valeu Paulo e todos que responderam, usando o clear() deu certo.
E usarei o Envers sim, mas para esse caso específico não posso, preciso fazer na unha mesmo.
Abraços!