Fórum org.hibernate.HibernateException: identifier of an instance of was altered from 1 to 2 - Alguém pode me ajudar ??? #423549
13/09/2012
0
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
Curtir tópico
+ 0Posts
19/08/2014
Thyago Benevides
Gostei + 0
20/08/2014
Ronaldo Lanhellas
1 2 3 | // 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.
Gostei + 0
29/12/2015
Diego Oliveira
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
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)