org.hibernate.HibernateException: identifier of an instance of was altered from 1 to 2 - Alguém pode me ajudar ???

13/09/2012

0

Msg. de erro: org.hibernate.HibernateException: identifier of an instance of was altered from 1 to 2

Resumidamente, abaixo, tenho a seguintes tabelas físicas no banco de dados MySQL.

Pedido
id_pedido(pk)

ItemPedido
id_item_pedido(pk)
id_pedido(fk)
id_produto(fk)

Produto
id_produto(pk)
----------------------------------------------------------------------------------------------------
1) Agora, veja a minha classe ou modelo Pedido:

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id_tb_pedido;

//1:n
@OneToMany(mappedBy="pedido")
private List<ItemPedido> listaItemPedido;

2) Agora, veja a minha classe ou modelo ItemPedido:

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id_tb_item_pedido;

//n:1
@ManyToOne
@JoinColumn(name="id_tb_pedido", nullable=false, referencedColumnName="id_tb_pedido")
private Pedido pedido;

//n:1
@ManyToOne
@JoinColumn(name="id_tb_produto", nullable=false, referencedColumnName="id_tb_produto")
private Produto produto;

3) Agora, veja a minha classe ou modelo Produto:

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id_tb_produto;

@Column
private String descricao_tb_produto;

//1:n
@OneToMany(mappedBy="produto")
private List<ItemPedido> listaItemPedido;

-------------------------------------------------------------------------------------------------------

4) Na View (XHTML), pgitempedido.xhtml:

<hutputLabel id="lbl_codigo_produto"
value="Produto"/>

<p:selectOneMenu id="som_codigo_prod"
value="#{movItemPedidoMB.itemPedidoAtual.produto.id_tb_produto}"
immediate="true" >

<f:selectItems value="#{movItemPedidoMB.checkBoxTelaProduto}" />
<f:ajax event="change" ></f:ajax>

</p:selectOneMenu >

<p:commandButton id="incluir_item_p"
value="Incluir"
update=":frm_cad_pedido :frm_lista_item_pedido"
action="#{movItemPedidoMB.incluir}"
ajax="true"
oncomplete="telaItemPedido.hide();"
rendered="true"/>

<p:commandButton id="alterar_item_p"
value="Alterar"
update=":frm_cad_pedido :frm_lista_item_pedido"
action="#{movItemPedidoMB.alterar}"
ajax="true" />

<p:commandButton id="excluir_item_p"
value="Excluir"
update=":frm_cad_pedido :frm_lista_item_pedido"
action="#{movItemPedidoMB.excluir}"
ajax="true"
oncomplete="telaItemPedido.hide();"
rendered="true"/>

5) A idéia é o usuário, selecionar o produto que ele deseja no combobox e então clicar no botão Alterar, quando ele clica no botão Alterar o seguinte método é chamado:
#{movItemPedidoMB.alterar}, segue a implementação do mesmo:

public String alterar() {
FacesContext fc = FacesContext.getCurrentInstance();
//ItemPedido itemPedidoAtual = getItemPedidoAtual();


try {

// beanPedido.getListaItemPedidoAtual().remove(itemPedidoAtual);

// itemPedidoAtual.setId_tb_produto(itemPedidoAtual.getProduto().getId_tb_produto());

// itemPedidoAtual.getProduto().setId_tb_produto(itemPedidoAtual.getProduto().getId_tb_produto());

itemPedidoServico.atualiza(itemPedidoAtual);

// getListaItemPedido().add(itemPedidoAtual);

// beanPedido.getListaItemPedidoAtual().add(itemPedidoAtual);


String mensagem = "Item de Pedido alterado com sucesso!";
fc.addMessage(null, FacesUtil.mensagem(mensagem));

} catch (Exception e) {
e.printStackTrace();
String mensagem = e.getLocalizedMessage();
fc.addMessage(null, FacesUtil.mensagemErro(mensagem));
}

return "/restrito/pgpedido";
}

6) Abaixo, segue o método que carrega os produtos no combobox do meu Bean ItemPedido:
#{movItemPedidoMB.checkBoxTelaProduto}

public List<SelectItem> getCheckBoxTelaProduto() {

List<SelectItem> itens = new ArrayList<SelectItem>(getListaProduto().size());

List<Produto> lista = getListaProduto();

for(Produto produto : lista){
itens.add(new SelectItem(produto.getId_tb_produto(), produto.getDescricao_tb_produto()));
}

return itens;
}

7) Abaixo, segue o value do <pelectedOneMenu...>:
#{movItemPedidoMB.itemPedidoAtual.produto.id_tb_produto}, veja que estou de dentro do objeto itemPedidoAtual, fazendo referência ao id_tb_produto do objeto produto. Logo, após o usuário selecionar o produto no combobox que ele deseja fazer o merge ou update na ItemPedidoAtual, ao clicar no botão Alterar e chamar o método #{movItemPedidoMB.alterar}, o Hibernate dispara a seguinte Exception:

java.lang.RuntimeException: javax.persistence.RollbackException: Error while committing the transaction
at br.com.sio.repositorio.RepositorioImpl.executaNaTransacao(RepositorioImpl.java:119)
at br.com.sio.repositorio.RepositorioImpl.atualiza(RepositorioImpl.java:46)
at br.com.sio.controller.servico.ItemPedidoServico.atualiza(ItemPedidoServico.java:40)
at br.com.sio.web.mb.MovItemPedidoBean.alterar(MovItemPedidoBean.java:274)
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.el.parser.AstValue.invoke(AstValue.java:264)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:27
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:8
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:11
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at br.com.sio.web.filter.FiltroAcesso.doFilter(FiltroAcesso.java:52)
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:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:16
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:9
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:11
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:93)
at br.com.sio.repositorio.RepositorioImpl.executaNaTransacao(RepositorioImpl.java:9
... 38 more
Caused by: javax.persistence.PersistenceException: org.hibernate.HibernateException: identifier of an instance of br.com.sio.model.jpa.entity.Produto was altered from 1 to 2at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1215)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:114
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:81)
... 39 more
Caused by: org.hibernate.HibernateException: identifier of an instance of br.com.sio.model.jpa.entity.Produto was altered from 1 to 2at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:85)
at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:190)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:147)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:76)
... 39 more

Ou seja, nas linhas que 'NEGRITEI' na Exception acima, aparentemente indica que tentou-se alterar o id_tb_produto no Model de Produto, sendo que era, apenas para alterar o Model ItemPedido, mais especificamente o id_tb_produto da tabela física de ItemPedido. Faço, uma ressalva, o meu Bean ItemPedido, como demonstrado acima, possui um atributo Produto produto e não um atributo Integer id_tb_produto.


Por favor, estou enfrentando este problema há 1 semana, procurei este problema no GUJ, porém, não vi ninguém descrevendo a solução.


Aguardo um retorno.


Danilo Cerne.
danilo.ge@hotmail.com
Programador Java Web Jsf 2.0 + TomCat 7 + Hibernate 3.2 + MySQL 5.2
Danilo Cerne

Danilo Cerne

Responder

Posts

19/08/2014

Thyago Benevides

Iai, Danilo Cerne conseguiu resolver o problema ? Estou com o mesmo problema.
Responder

20/08/2014

Ronaldo Lanhellas

Bom, creio que a confusão esteja aqui:


// itemPedidoAtual.setId_tb_produto(itemPedidoAtual.getProduto().getId_tb_produto());

// itemPedidoAtual.getProduto().setId_tb_produto(itemPedidoAtual.getProduto().getId_tb_produto());


o objeto "itemPedidoAtual" está setando um ID para o produto e depois mudando o ID do produto, reveja esse trecho.
Responder

29/12/2015

Diego Oliveira

Cara, estava passando por um problema igual ao seu, e pesquisando sobre o erro, vi seu post.
Eu consegui resolver o problema usando a propriedade detach do entityManager.

Quando vocês usa este cara, ele limpa o contexto da persistência, fazendo com que seu objeto seja renovado para uma nova iteração no banco de dados.

ex de detach:

entityManager.detach(nomeObjeto);
//abaixo o objeto manipulado

feito isso, você consegue manipular o objeto e fazer qualquer iteração com o banco de dados.

Li sobre, aqui: https://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html
Responder

APRENDA A PROGRAMAR DO ZERO AO PROFISSIONAL

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar