[Resolvido] NonUniqueObjectException

3 respostas
Ace

Bom dia pessoal,
Já venho alguns dias fritando a cabeça, com uma rotina simples onde a mesma faz o seguinte:

Em uma listagem em minha jsp, tenho um click “voto” abaixo de cada produto, e ao ser clicado, armazena no meu banco o usuario da sessão e em qual produto foi votado” simples assim!

o problema é que não estou conseguindo fazer isso funcionar. Se alguém tiver com um pouco de tempo, e paciencia para a judar um novato, peço ajuda dos mais experientes, pois infelizmente não estou conseguindo resolver isso sozinho! Mais uma vez Obrigado Pessoal :smiley:
seguem os dados:

Action

public ActionForward votar(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {					
		
			HttpSession session = request.getSession();
			Voto voto = new Voto();
			String valor = request.getParameter("produto");	// aqui tras o code do produto		
			
			if(session.getAttribute("userSession") != null){
				
				UsuarioClube usuario = (UsuarioClube) session.getAttribute("userSession");
				
				voto.setProduto(new Produto());
				voto.getProduto().setCode(Long.parseLong(valor));
				voto.votar(); // metodo de contagem 
				
				voto.setUsuario(new UsuarioClube());
				voto.setUsuario(usuario);
				session.setAttribute("usuario", usuario.getCpf());
				
				DAOFactory.getVotoDao().saveOrUpdate(voto);
			}			
						
			
        	return mapping.findForward("voto");			
						
	}

saveOrUpdate

public abstract class AbstractDAO {

	Session session;
	
	public void saveOrUpdate(Object obj) throws ConstraintViolationException, SQLException, HibernateException, Exception {
		session.saveOrUpdate(obj);
		session.flush();
	}
}

Voto

@Entity
@Table(name = "VOTO",
		uniqueConstraints={
		@UniqueConstraint(columnNames={"usuario","produto"})
		}
		)
public class Voto implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	
	@Id
	@JoinColumn(name = "usuario", referencedColumnName = "cpf")    
    @OneToOne     
    private UsuarioClube usuario;    
       
	@Id
    @JoinColumn(name = "produto", referencedColumnName = "code")    
    @OneToOne
    private Produto produto;


   //Getter & Setter

Relacionamento

Erro

17/04/2012 09:52:37 org.apache.struts.chain.commands.ExceptionCatcher postprocess
AVISO: Exception from exceptionCommand 'servlet-exception'
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [br.com.model.Voto#br.com.model.Voto@190efc]
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:190)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:143)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
	at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
	at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
	at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:673)
	at br.com.dao.AbstractDAO.saveOrUpdate(AbstractDAO.java:17)
	at br.com.action.SalaLeituraAction.votar(SalaLeituraAction.java:80)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:269)
	at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:170)
	at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
	at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
	at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
	at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:305)
	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
	at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
	at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at br.com.filter.ClubeFilter.doFilter(ClubeFilter.java:51)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at br.com.filter.HibernateFilter.doFilter(HibernateFilter.java:42)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

3 Respostas

WRYEL

não entendi ao certo o que você quer fazer, mas, me parece que tem ai uma chave composta em Voto. Para chave composta, utilize EmbeddedId: http://www.java2s.com/Code/Java/JPA/EmbeddedCompoundPrimaryKey.htm

Não sei se é correto afirmar na sua regra de negócio, mas, seria mais elegante, dentro do seu DAO, você checar antes pra ver se não tem um Voto com seu ID composto, se tiver, você usa a mesma referência para dar update, caso contrario, você faz o insert :o)

[]'s

Ace

olá WRYEL,
Cara muito obrigado pelo retorno, como este é um sistema legado, estou totalmente perdido com isso aqui. :?
e tambem não sei como fazer essas alterações proposta por vc poderia me mostrar mais ou menos pra ver se consigo algo por aqui?
todos os metodos que estão sendo utilizados por essa ação está postada aqui.
vlw

Ace

Pessoal no meu caso estava tentando carregar 2 objetos com o mesmo id na mesma session. por isso dava essa exception.
alterei o

saveOrUpdate de

public void saveOrUpdate(Object obj) throws ConstraintViolationException, SQLException, HibernateException, Exception {
	session.saveOrUpdate(obj);
	session.flush();			
	}

saveOrUpdate para

public void saveOrUpdate(Object obj) throws ConstraintViolationException, SQLException, HibernateException, Exception {
		try {
			session.saveOrUpdate(obj);
			session.flush();	
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			session.clear();
		}
		
	}

Não sei se essa é uma solução mais correta a ser tomada, mas nesse caso funcionou.

Obrigado a todos pela atenção mais uma vez.

Criado 17 de abril de 2012
Ultima resposta 17 de abr. de 2012
Respostas 3
Participantes 2