Bom dia Pessoal.
Tenho uma tela de pedidos em jsf, onde se o valor do pedido for 0 (zero) eu preciso excluir o pedido.
Utilizo hibernate com os pojos, mapeamentos e implementações estão em um projeto separado do projeto web.
o pedido é incluido e gravado normalmente, mas quando tento excluir o pedido, recebo a exception abaixo:
WARNING: #{pedidosBean.excluiPedido}: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [br.com.jvmsoftware.deliveryjava.mapeamento.DlvPedidos#85]
javax.faces.FacesException: #{pedidosBean.excluiPedido}: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [br.com.jvmsoftware.deliveryjava.mapeamento.DlvPedidos#85]
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
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:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:724)
Caused by: javax.faces.el.EvaluationException: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [br.com.jvmsoftware.deliveryjava.mapeamento.DlvPedidos#85]
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
... 19 more
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [br.com.jvmsoftware.deliveryjava.mapeamento.DlvPedidos#85]
at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:590)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:99)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:52)
at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:766)
at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:744)
at br.com.jvmsoftware.deliveryjava.implement.DlvPedidosImp.excluiPedido(DlvPedidosImp.java:53)
at br.com.jvmsoftware.delivery.bean.PedidosBean.excluiPedido(PedidosBean.java:199)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.el.parser.AstValue.invoke(AstValue.java:191)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 20 more
Meu objeto pedido é único na bean, por isso, não estou entendendo o porque do erro (metodo excluiPedido)
meu bean:
@ManagedBean
@SessionScoped
public class PedidosBean implements Serializable {
private AcsUsuariosImp usuImp = new AcsUsuariosImp();
private DlvCardapiosImp cardImp = new DlvCardapiosImp();
private DlvPedidosImp pedImp = new DlvPedidosImp();
private DlvConfigImp confImp = new DlvConfigImp();
private DlvSituacaoPedidoImp sitPedImp = new DlvSituacaoPedidoImp();
private DlvTipoPedidoImp tipoPedImp = new DlvTipoPedidoImp();
private DlvFormaPagamentosImp forPagImp = new DlvFormaPagamentosImp();
private DlvTipoPagamentosImp tipoPagImp = new DlvTipoPagamentosImp();
private DlvEntregadoresImp entImp = new DlvEntregadoresImp();
private AcsClientesImp cliImp = new AcsClientesImp();
public AcsClientes cliente = new AcsClientes();
public DlvPedidos pedido = new DlvPedidos();
public AcsUsuarios usuario = new AcsUsuarios();
public DlvPedidoItens itemPedido = new DlvPedidoItens();
public DlvConfig config = new DlvConfig();
public Date diaPedido = new java.util.Date();
public Boolean exibeTabItens = false;
public Boolean incluiPedido = true;
public Boolean alteraPedido = false;
public Boolean imprimePedido = false;
public List<DlvCardapios> listCardapios;
public List<DlvPedidos> listPedidos;
public List<AcsClientes> listClientes;
public List<DlvEntregadores> listEntregadores;
public List<DlvSituacaoPedido> listSituacaoPedidos;
public List<DlvTipoPedido> listTipoPedidos;
public List<DlvFormaPagamento> listFormaPagamentos;
public List<DlvTipoPagamento> listTipoPagamentos;
public List<DlvPedidoItens> listItensPedido;
public String psw = null;
FacesMessage msg = null;
public PedidosBean() {
// nova instancia de ClientesBean
diaPedido = new java.util.Date();
listSituacaoPedidos = sitPedImp.listSituacaoPedido();
listTipoPedidos = tipoPedImp.listTipoPedidoNotDif();
listFormaPagamentos = forPagImp.listFormaPagamento();
listTipoPagamentos = tipoPagImp.listTipoPagamento();
}
public void startIncluiPedido() {
System.out.println("PedidosBean.startIncluiPedido: ");
pedido = new DlvPedidos();
DlvSituacaoPedido sit = sitPedImp.getById(1);
DlvTipoPedido tipoPedido = tipoPedImp.getById(1);
exibeTabItens = false;
alteraPedido = false;
incluiPedido = true;
listItensPedido = new ArrayList<DlvPedidoItens>();
config = confImp.getConfig(usuario.getAcsEmpresa());
listEntregadores = entImp.listEntregadores(usuario.getAcsEmpresa(), new Long(0), "", new Long(0));
pedido.setAcsEmpresa(usuario.getAcsEmpresa());
pedido.setDlvSituacaoPedido(sit);
pedido.setDlvTipoPedido(tipoPedido);
pedido.setAcsClientes(cliente);
}
public void incluiPedido() {
System.out.println("PedidosBean.incluiPedido: ");
pedido.setTotalPedido(BigDecimal.ZERO);
pedido.setValorPago(BigDecimal.ZERO);
pedido.setTroco(BigDecimal.ZERO);
pedido.setDtHoraPedido(new java.util.Date());
pedido.setAcsUsuariosByUsuarioPedido(usuario);
pedImp.incluiPedidos(pedido);
//System.out.println("PedidosBean.incluiPedido: pedido: " + pedido.getIdPedido());
// exibe tabela de itens
exibeTabItens = true;
// novo item pedido
itemPedido = new DlvPedidoItens();
alteraPedido = true;
incluiPedido = false;
listCardapios();
listPedidos();
}
public void alteraPedido() {
System.out.println("PedidosBean.incluiPedido: ");
// exibe tabela de itens
exibeTabItens = true;
imprimePedido = true;
// novo item pedido
itemPedido = new DlvPedidoItens();
calculaValorPedido();
System.out.println("PedidosBean.alteraPedido");
if(pedido.getValorPago().compareTo(BigDecimal.ZERO) == 0 || pedido.getValorPago().compareTo(pedido.getTotalPedido()) < 0) {
System.out.println("PedidosBean.alteraPedido - valor pago = 0");
pedido.setValorPago(pedido.getTotalPedido());
}
calculaTroco();
listCardapios();
listItensPedido();
// atualiza lista de pedidos
listPedidos();
pedImp.salvaPedidos(pedido);
}
public void excluiPedido() {
System.out.println("PedidosBean.excluiPedido: idPedido: " + pedido.getIdPedido());
System.out.println("PedidosBean.excluiPedido: totalPedido: " + pedido.getTotalPedido());
exibeTabItens = false;
if (pedido.getIdPedido() != null ) {
if (pedido.getTotalPedido() == null || pedido.getTotalPedido().compareTo(BigDecimal.ZERO) == 0) {
System.out.println("if (pedido.getIdPedido() == null) - idPedido: " + pedido.getIdPedido());
listItensPedido();
if (!listItensPedido.isEmpty()) {
for (int i = 0; i < listItensPedido.size(); i++) {
itemPedido = listItensPedido.get(i);
excluiItenPedido();
}
}
pedImp.salvaPedidos(pedido);
pedImp.excluiPedido(pedido); // o problema é nesta chamada
} else {
if (!"CONSUMIDOR".equals(pedido.getAcsClientes().getNome())) {
// verifica itens de pedido
listItensPedido();
calculaValorPedido();
}
pedImp.salvaPedidos(pedido);
}
alteraPedido = false;
incluiPedido = true;
pedido = new DlvPedidos();
cliente = new AcsClientes();
listPedidos();
}
}
public void cancelaPedido() {
...
}
public void incluiItenPedido() {
...
}
public void excluiItenPedido() {
...
}
public void listPedidos(){
...
}
public void listItensPedido(){
...
}
public void listCardapios(){
...
}
public void calculaValorPedido() {
...
}
public void calculaTroco() {
...
}
// getters e setters
.....
}
minha classe de implementação do hibernate:
public class DlvPedidosImp implements Serializable {
SessionFactory sf = getSessionFactory();
Session session = sf.openSession();
public DlvPedidosImp() {
}
public void salvaItemPedido(DlvPedidoItens itemPedido) {
session.beginTransaction();
session.flush();
session.saveOrUpdate(itemPedido);
session.beginTransaction().commit();
session.flush();
}
public void incluiPedidos(DlvPedidos pedido) {
session.beginTransaction();
session.saveOrUpdate(pedido);
session.beginTransaction().commit();
session.flush();
}
public void salvaPedidos(DlvPedidos pedido) {
session.beginTransaction();
session.merge(pedido);
session.beginTransaction().commit();
session.flush();
}
public void excluiPedido(DlvPedidos pedido) {
session.beginTransaction();
session.delete(pedido); // O ERRO É GERADO NESTE PONTO
session.beginTransaction().commit();
session.flush();
}
}
Já fiz a chamada por um arquivo de testes, e funciona:
public void pedido() {
AcsUsuariosImp usuImp = new AcsUsuariosImp();
DlvSituacaoPedidoImp sitImp = new DlvSituacaoPedidoImp();
DlvFormaPagamentosImp forImp = new DlvFormaPagamentosImp();
DlvTipoPagamentosImp tPagImp = new DlvTipoPagamentosImp();
DlvTipoPedidoImp tPedImp = new DlvTipoPedidoImp();
AcsUsuarios usuario = usuImp.getUsuariosById(1);
DlvSituacaoPedido sit = sitImp.getById(1);
DlvFormaPagamento form = forImp.getById(1);
DlvTipoPagamento tPag = tPagImp.getById(1);
DlvTipoPedido tPed = tPedImp.getById(1);
cliente = cliImp.getById(10);
empresa = empImp.getEmpresaById(1);
pedido.setAcsClientes(cliente);
pedido.setAcsEmpresa(empresa);
pedido.setAcsUsuariosByUsuarioPedido(usuario);
pedido.setDtHoraPedido(new java.util.Date());
pedido.setDlvSituacaoPedido(sit);
pedido.setDlvFormaPagamento(form);
pedido.setDlvTipoPagamento(tPag);
pedido.setDlvTipoPedido(tPed);
pedImp.incluiPedidos(pedido);
System.out.println("pedido incluido com sucesso!");
pedImp.excluiPedido(pedido);
System.out.println("pedido excluido com sucesso!");
}
O problema só acontece quando estou utilizando a tela de pedidos (.xhtml)
Como contornar este problema??