JPA - Registry error not found right after insertion

Asked

Viewed 393 times

5

A question about JPA procedures, because of a mistake that happened and I’m not getting it.

I’m taking care of a part of the system that feeds a card order table. It searches if the user that the request references owns the card, and it inserts it before entering into the credit table. However it gives a parent key not found error even by inserting before in the card table.

Below what is presented on the console:

[EL Fine]: sql: 2015-04-24 16:22:50.166--ClientSession(1319007734)--Connection(2018078818)--Thread(Thread[main,5,main])--INSERT INTO CARTAO (CD_CARTAO, |demais campos|) VALUES (?, |demais campos|)
    bind => [10905487, |demais campos|]
[EL Finest]: query: 2015-04-24 16:22:50.17--UnitOfWork(459973678)--Thread(Thread[main,5,main])--Execute query UpdateObjectQuery(br.com.virtus.sgc.model.Pedido@21144823)
[EL Fine]: sql: 2015-04-24 16:22:50.171--ClientSession(1319007734)--Connection(2018078818)--Thread(Thread[main,5,main])--UPDATE PEDIDO SET CD_FASE_ATUAL = ? WHERE (CD_PEDIDO = ?)
    bind => [6, 22557]
[EL Finest]: query: 2015-04-24 16:22:50.174--UnitOfWork(459973678)--Thread(Thread[main,5,main])--Execute query InsertObjectQuery(br.com.virtus.sgc.model.Cardcredito@6e8d1800)
[EL Fine]: sql: 2015-04-24 16:22:50.175--ClientSession(1319007734)--Connection(2018078818)--Thread(Thread[main,5,main])--INSERT INTO CARDCREDITO (ID_CARDCREDITO,  VL_CREDITO, CD_CARTAO, CD_PEDIDO) VALUES (?, ?, ?, ?)
    bind => [1721388, 356, 10905487, 22557]
[EL Fine]: sql: 2015-04-24 16:22:50.182--ClientSession(1319007734)--Thread(Thread[main,5,main])--SELECT 1 FROM DUAL
[EL Warning]: 2015-04-24 16:22:50.188--UnitOfWork(459973678)--Thread(Thread[main,5,main])--Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: ORA-02291: restrição de integridade (SGCMASTER.RI_CARDCREDITO) violada - chave-pai não localizada

In the console shows the same card number: 10905487. This ID is generated by an Oracle Sequence.

And of course, the code:

public void processar(){
        BigDecimal icCardcredito;
        try {
            em.getTransaction().begin();
            List<Pedido> lstAProcessar  = this.listagemPedidosAProcessar();
            TipoFasePedido proc         = new TipoFasePedidoImpl().pesquisarPorId(Long.valueOf(qryParam.pesquisarPorNmChave("CD_FASE_PEDIDO_PROCESSADO").getNmValor()));
            HistoricoPedido histPed     = new HistoricoPedido();            
            for(Pedido ped:lstAProcessar){
                ped.setCardcreditos(new ArrayList<Cardcredito>());
                icCardcredito = BigDecimal.ONE;
                List<PedidoDetalhe> infoPedido = this.listaValores(ped);
                for (PedidoDetalhe info: infoPedido){
                    Produto prod = ped.getProduto();
                    Cliente clie = ped.getCliente();
                    String  cpf  = info.getCdCpf();
                    Cartao  card = new Cartao(); 
                    card         =  this.pegaCartao(cpf, clie, prod);//Aqui ele busca o cartão
                    boolean tem  = (card instanceof Cartao);
                    if (!(tem)){
                        card = novoCartao(info);
                        em.persist(card);
                    }
                    Cardcredito itemCred = new Cardcredito();
                    itemCred.setCartao(card);
                    itemCred.setVlCredito(info.getVlCredito());
                    ped.addCardcredito(itemCred);
                    em.merge(ped);
                    icCardcredito.add(BigDecimal.ONE);
                }
                histPed = new HistoricoPedido();

                histPed.setTipoFasePedido(proc);
                histPed.setDtFasePedido(new Date());
                histPed.setNmOperador(qryUtils.nmUsuarioSistema());

                ped.setTipoFasePedido(proc);
                ped.addHistoricoPedido(histPed);

                em.merge(ped);                      
            }       
        em.getTransaction().commit();
        } catch (Exception ex) {
            em.getTransaction().rollback();
            System.out.println("---ERRO!----" + ex.getMessage());
        }

    }

My question is:

What’s the explanation for this happening? Has something to do with cascadeType between the tables?

I tested with ALL and PERSIST and both made this mistake.

Thanks!

[Updating]

I was checking the base and I realized that the triggers were active (to deal with the sequences, I’m using the @GeneratedValue and @SequenceGenerator in the model. ) Inactive and by the visa was this.

But still something curious happened.

The card table has a history related table. It is fed during the process, and after you have disabled the triggers, was giving error exactly on it (parent key not found). I took the information TIMESTAMP of the date and put DATE and went through this stage normally.

What relationship exists between date fields and a PK?

  • You probably have the "classic" "read commited" problem. To avoid taking a risk of me making a wrong guess, try committing the first transaction and then, do the search normally and see if the record is found and post here the result.

  • Silly question, is rolling commit in transaction?

  • No... as I mentioned above, it was a Trigger Before Insert of the Oracle that called the Sequence. By disabling, leaving the sequence mentioned in the class, everything worked out.

  • Thiago, welcome to [en.so]! It would be interesting to post your solution as an answer to your own question, as it makes it easier for those who visit the site to understand how to solve the problem. As for your other question about triggers, it would be better to post a separate question, because here it will receive little or no attention, besides escaping from the original topic. Hug!

  • @utluiz The separate question I already have the solution too. I must ask the question And the solution or in Stack Overflow has a space already intended for this?

  • 1

    James, apparently you found the place of the answers. Whenever you find the solution to your own problem do not hesitate to post. We have no problems with this, on the contrary, the important thing is to share knowledge. Just don’t do it if the solution isn’t a real answer, like "I gave up and did something else". Hug!

Show 1 more comment

1 answer

0


Eventually I checked the database and noticed that the triggers were active. Just like @Generatedvalue and @Sequencegenerator were being used in the class.

Soon, the id was updated within the class, but was changed at the base by Trigger, who called again Quence.

I inactivated Rigger, (so Quence is updated only one way, and only once) and it all worked out.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.