Merge not committed


(Víctor Sánchez) #1

Hi, I have this method to save a List of entities, the information comes from other non-Cuba database(LiTienda), I compare with Cuba database(LineaSubPedido) and if exists I update the entity but sometimes changes are not committed. With a database log I verify that the list of entities comes with information, so there is not problem in that part.

All the transactions in services I call are closed and committed, so I do not know what I am doing wrong

public void modificarLineasPedido(List<LiTienda> lineasLitienda) {
        LineaSubPedido lsp = null;
        String codTienda = "";
        Pedido ped = null;
        SubPedido subped = null;
        for(LiTienda lt: lineasLitienda) {
            subped = pedidosService.comprobarSubPedido(lt.getNped(), lt.getId().getTienda());
            if (subped != null) {
                try (Transaction tx = persistence.createTransaction()) {
                    TypedQuery<LineaSubPedido> queryLineasSubPedido;
                    EntityManager em = persistence.getEntityManager();
                    queryLineasSubPedido = em.createQuery("SELECT linea FROM pedidos$LineaSubPedido linea WHERE linea.idArticulo = :refe AND linea.subPedido.codPraxis = :subped", LineaSubPedido.class);
                    queryLineasSubPedido.setParameter("refe", lt.getId().getRefe());
                    queryLineasSubPedido.setParameter("subped", subped.getCodPraxis());
                    lsp = queryLineasSubPedido.getFirstResult();
                    tx.commit();
                }
                ped = pedidosService.buscarPedidoPorSubPedido(subped);
                codTienda = pedidosService.buscarTiendaPorPedido(ped);
                if (lsp != null) {
                    try (Transaction tx = persistence.createTransaction()) {
                       EntityManager em = persistence.getEntityManager();
                        lsp.setUnidadesServidas(lsp.getUnidadesServidas().add(lt.getCant()));
                        em.merge(lsp);
                        tx.commit();
                    }
                    logService.nuevaEntrada("Línea", "Modificacion", "Tienda " + codTienda + " | Pedido " + ped.getIdPedido() + " | Subpedido " + subped.getCodPraxis()
                            + " | Artículo " + lsp.getIdArticulo() + " " + lsp.getDescArticulo() + " unidades pedidas " + lsp.getUnidadesPedidas() + " unidades servidas " + lsp.getUnidadesServidas());
                } else {
                    try (Transaction tx = persistence.createTransaction()) {
                        EntityManager em = persistence.getEntityManager();
                        lsp = metadata.create(LineaSubPedido.class);
                        lsp.setSubPedido(subped);
                        lsp.setDescArticulo(lt.getDesc1());
                        lsp.setUnidadesServidas(lt.getCant());
                        lsp.setUnidadesPedidas(BigDecimal.ZERO);
                        lsp.setUnidadesDistribucion(lt.getUnca());
                        lsp.setIdArticulo(lt.getId().getRefe());
                        em.persist(lsp);
                        tx.commit();
                    }
                    logService.nuevaEntrada("Línea", "Modificacion", "Nueva línea - > Tienda " + codTienda + " | Pedido " + ped.getIdPedido() + " | Subpedido " + subped.getCodPraxis()
                            + " | Artículo " + lsp.getIdArticulo() + " " + lsp.getDescArticulo() + " unidades pedidas " + lsp.getUnidadesPedidas() + " unidades servidas " + lsp.getUnidadesServidas());

                }
            }
        }
        recogerSubPedidos(lineasLitienda);
    }

I implemented Transaction Listener to verify that changes were committed, and there is not any record on log

@Component("pedidos_LitiendaTransactionListener")
public class LitiendaTransactionListener implements AfterCompleteTransactionListener {

    @Inject
    private LogService logService;

    @Override
    public void afterComplete(boolean committed, Collection<Entity> detachedEntities) {
        for (Entity entity : detachedEntities) {
            if (entity instanceof LineaSubPedido && !committed) {
                logService.nuevaEntrada("Línea", "Not saved", "Tienda " +
                        ((LineaSubPedido) entity).getSubPedido().getPedidoTienda().getTienda().getIdTienda() +
                        ((LineaSubPedido) entity).getSubPedido().getPedidoTienda().getTienda().getDescTienda() + " | " +
                        ((LineaSubPedido) entity).getSubPedido().getPedidoTienda().getIdPedido() + " | " +
                        ((LineaSubPedido) entity).getSubPedido().getCodPraxis() + " | " +
                        ((LineaSubPedido) entity).getIdArticulo() + " " + ((LineaSubPedido) entity).getUnidadesServidas());
            }
        }
    }
}

Thanks in advance!


(Konstantin Krivopustov) #2

Hi Víctor,

Your code looks correct from the framework usage perspective, except that you could do all loading/saving in one transaction for each iteration.

So the problem must be in the logic. Are you sure pedidosService.comprobarSubPedido() returns a non-null result for all input data? Also, your LineaSubPedido entity will not be updated if it already contains the same data, i.e. lt.getCant() is zero.