Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Erro ao realizar UPDATE com JPA

Estou tendo problema quando tento realizar um update com JPA com a instrução:

ObjetoDE = thisObjetoBF.update(ObjetoDE);

[ERROR ] Exception [EclipseLink-5010] (Eclipse Persistence Services - 2.4.2.v20130514-5956486): org.eclipse.persistence.exceptions.OptimisticLockException Exception Description: The object [ObjetoDE{ChaveUidK=355}] cannot be merged because it has changed or been deleted since it was last read. Class> com.xxx.yyyy.domain.admin.entity.TabelaDE

Comentei todos os campos passando para o Update somente a chave do registro e mesmo assim persiste o erro, Teriam alguma idéia ?

Desde já agradeço.

7 respostas

Olá Antonio, o problema é que o registro que vc está tentando atualizar, foi atualizado ou mesmo excluído por outro usuário.

O EclipseLink está dando esta exceção para que vc possa fazer tratamento para este tipo de situação, por exemplo: Vc poderia dar uma mensagem para o usuário que o registro que está sendo editado foi alterado por outro usuário. Ou mesmo adotar outra estratégia.

Att.

Eduardo obrigado pelo retorno, então estou tentando dar um update nesse registro utilizando o JPA. Não consegui entender o motivo que ele está recusando se é update. abaixo meu código desse trecho:

(InterfaceActionEnum.UPDATE.equals(ObjetotDE.getAction())) { LOGGER.info("######## ATUALIZANDO ......"); ObjetoCorporativoDE.setUpdateProcessN(this.getInferfaceC()); ObjetoCorporativoDE = this.objetoCorporativoBF.update(objetoCorporativoDE);

Obrigado.

Consegue colocar as classes envolvidas para que eu possa entender melhor.

Att.

É um ETL que pega dados de uma tabela oracle realiza algumas consistências e grava ou atualiza os dados no SQL Server. Segue os métodos que fazem isso:

//Nesse método ele verifica qual a ação setada (UPDATE, INSET, DELETE) e envia via JPA.

private void processList(List<PecasSessaoPDE> pecaSessaoList) {

    List<Object[]> pecasSessaoDivList = loadWorksDivList(pecaSessaoList);

    PecasSessaoDE pecasSessaoCorporativoDE = null;
    PecasSessaoPDE pecasSessaoPDE = null;

    for (Iterator<PecasSessaoPDE> iterator = pecaSessaoList.iterator(); iterator.hasNext();) {

        pecasSessaoPDE = iterator.next();
        pecasSessaoCorporativoDE  = new PecasSessaoDE();

        this.addLineNumber();

        try {
                pecasSessaoCorporativoDE = parse(pecasSessaoCorporativoDE, pecasSessaoPDE, pecasSessaoDivList);

                if (InterfaceActionEnum.INSERT.equals(pecasSessaoPDE.getAction())) {                    
                    LOGGER.info("######## INSERINDO pecas SUPERSESSION ......");                    
                    pecasSessaoCorporativoDE.setCreateProcessN(this.getInferfaceC());
                    this.pecasXSessaoCorporativoBF.create(pecasSessaoCorporativoDE);

                } else if (InterfaceActionEnum.UPDATE.equals(pecasSessaoPDE.getAction())) {                    
                    LOGGER.info("######## ATUALIZANDO pecas SUPERSESSION ......");
                    pecasSessaoCorporativoDE.setUpdateProcessN(this.getInferfaceC());
                    pecasSessaoCorporativoDE = this.pecasXSessaoCorporativoBF.update(pecasSessaoCorporativoDE);

                } else if (InterfaceActionEnum.DELETE.equals(pecasSessaoPDE.getAction())) {                    
                    LOGGER.info("######## DELETANDO pecas SUPERSESSION ......");
                    this.pecasXSessaoCorporativoBF.delete(pecasSessaoCorporativoDE.getPartSessaoUidK());                    
                }

                this.addSuccess();

                // Marca no P registros ja processados no corporativo
                // int result = this.pecasSessaoPBF.update(pecasXSessaoPDE);                
                // LOGGER.info(result +"######## Registro(s) Atualizado(s) com sucesso no P......");

        } catch (FRestClientValidationException ex) {
            String message = "";

            if (ex.getValidationFailureResponseTO() != null && ex.getValidationFailureResponseTO().getFailureList() != null && !ex.getValidationFailureResponseTO().getFailureList().isEmpty()) {
                String key = ex.getValidationFailureResponseTO().getFailureList().get(0).getMessageCode();
                message = this.bundle.getString(key);
            }
            this.addError("Exception1 - Country: " + this.getCountry() +
                    " - Div: " + this.DivDE.getBkDivC() +
                    " - Produto : " + pecasSessaoPDE.getCodigoProducto().toString() +
                    " - substituto: " + pecasSessaoPDE.getCodigosubstituto() +
                    " - ERROR: " + message);
        } catch (Exception e) {

            addError("Exception1 - Country: " + this.getCountry() +
                    " - Div: " + this.DivDE.getBkDivC() +
                    " - Produto : " + pecasSessaoPDE.getCodigoProducto().toString() +
                    " - substituto: " + pecasSessaoPDE.getCodigosubstituto()
                    , e);
        }
    }
}

//Aqui em resumo o objeto é alimentado e seta a ação protected PecasSessaoDE parse(PecasSessaoDE de, PecasSessaoPDE pecasSessaoPDE, List<Object[]> pecasSessaoDivList) throws Exception {

    Object[] aux = getPartDivUidK(pecasSessaoPDE,pecasSessaoDivList);
    PecasSessaoDE teste = null;

    BigDecimal P_serial_c = TypeHelper.getBigDecimal(aux[0]);
    Long codigo_substituto = TypeHelper.getLong(aux[1]);

    // key tb_100_to
    BigInteger pecaFromUidK = TypeHelper.getBigInteger(aux[2]);
    // key tb_104_to
    BigInteger pecaDivFromUidK = TypeHelper.getBigInteger(aux[3]);
    // key tb_100_from
    BigInteger pecaToUidK = TypeHelper.getBigInteger(aux[4]);
    // key tb_104_from
    BigInteger pecaDivToUidK = TypeHelper.getBigInteger(aux[5]);                            
    // key tb_104 
    BigInteger superSessionUidK = TypeHelper.getBigInteger(aux[6]);


    if (!Utils.isNull(aux) && aux.length > 0) {
        // key 104
        //de.setPartSessaoUidK(superSessionUidK);                    
        // 7 win104_create_user_c
        //de.setCreateUserC(TypeHelper.getString(aux[7]));
        // 8 win104_create_s
        //de.setCreateS(TypeHelper.getTimestamp(aux[8]));                
        // 9 win104_create_process_n 
        //de.setCreateProcessN(TypeHelper.getString(aux[9]));
        // 10 win104_update_user                
        //de.setUpdateUserC(TypeHelper.getString(aux[10]));
        // 11 win104_update_s                                
        //de.setUpdateS(TypeHelper.getTimestamp(aux[11]));
        // 12 win104_update_process_n
        //de.setUpdateProcessN(TypeHelper.getString(aux[12]));

        pecasSessaoPDE.setAction(InterfaceActionEnum.UPDATE);
    } else {

        pecasSessaoPDE.setAction(InterfaceActionEnum.INSERT);
    }

return de;        
}

Desde já obrigado. Um abraço.

solução!

Entendi.

O que pode estar acontecendo é que nessa massa de registro/operações (IN, UP, DE), algum registro está repetido (pela PK), isto poderia provocar 2 updates no mesmo registro.

Provavelmente vc tem uma transação de banco de dados para todo o processamento, daí o JPA identifica no momento do segundo update, que o registro já sofreu um update, gerando a exception org.eclipse.persistence.exceptions.OptimisticLockException.

Se esta situação se confirmar, vc pode eliminar os updates intermediários e deixar apenas o último, caso trate-se de operações de UPDATE. Possivelmente poderia ser outros casos, por exemplo um DELETE e depois um UPDATE no mesmo registro (mesma PK), neste caso o segundo UPDATE não faria sentido.

O que posso deduzir da situação é isto, mas precisa confirmar olhando os dados, verificando se existe dados repetidos.

Espero que ajude.

Att.

Cara é isso mesmo, debugando vi que alguns registros ele realiza um Update e no próximo ele dá o exception, mas como tratar isso ?

Obrigado

Acho que podes seguir essa linha:

Se esta situação se confirmar, vc pode eliminar os updates intermediários e deixar apenas o último, caso trate-se de operações de UPDATE. Possivelmente poderia ser outros casos, por exemplo um DELETE e depois um UPDATE no mesmo registro (mesma PK), neste caso o segundo UPDATE não faria sentido.

Att.