Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[eclipselink-users] NullPointerException returned using a StoredProcedureCall class

Hi,

I am developing a JPA, EJB and JSF 2.0 web app. I persist an entity PedidoUsuario and after it I want to get its PK in
the corresponding table ALMACEN.PEDIDO_USUARIO. To persist the entity I use an special EJB that calls another EJBs.

Here is the EJB,

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class ManejadorPedido {
   
    @PersistenceContext(unitName = "AlmacenJPA")
    private EntityManager em;
    @Resource
    private SessionContext context;
    @EJB
    private PedidoUsuarioFacade pedidoUsuarioFacade;
    @EJB
    private PiezaPedidaFacade piezaPedidaFacade;
    @EJB
    private ObtenerMaxIdPedidoUsuario obtenerMaxIdPedidoUsuario;

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public long placeOrder(Usuario usuario, ShoppingCart cart) {

        try {
            //Usuario usuario = addUsuario(nombre, apellidos, email, telefono, username, password);
            PedidoUsuario pedido = addPedido(usuario, cart);
            long orderId = obtenerMaxIdPedidoUsuario.ObtenerMaxId();
            addPedidoItems(orderId, cart);
            return orderId;
        } catch (Exception e) {
            e.printStackTrace();
            context.setRollbackOnly();
            return 0L;
        }
    }

    /*
    private Usuario addUsuario(String nombre, String apellidos, String email, String telefono, String username, String password) {

        Usuario usuario = new Usuario();
        usuario.setNombre(nombre);
        usuario.setApellidos(apellidos);
        usuario.setEmail(email);
        usuario.setTelefono(telefono);
        usuario.setUsername(username);
        usuario.setPassword(password);

        em.persist(usuario);
        return usuario;
    }
    */

    private PedidoUsuario addPedido(Usuario usuario, ShoppingCart cart) {

        // set up customer order
        PedidoUsuario order = new PedidoUsuario();
        order.setIdUsuario(new BigDecimal(usuario.getIdUsuario()));
        java.util.Date utilDate = Calendar.getInstance().getTime();
        java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
        order.setFechaPedido(sqlDate);
        cart.calculateTotal();
        order.setTotal(BigDecimal.valueOf(cart.getTotal()));

        // create confirmation number
        Random random = new Random();
        int i = random.nextInt(999999999);
        order.setNumeroConfirmacion(new BigDecimal(i));

        //em.persist(order);
        pedidoUsuarioFacade.create(order);
        return order;
    }

    private void addPedidoItems(long orderId, ShoppingCart cart) {

        //em.flush();

        List<ShoppingCartItem> items = cart.getItems();

        // iterate through shopping cart and create OrderedProducts
        for (ShoppingCartItem scItem : items) {

            long idPieza = scItem.getPieza().getIdPieza();

            // set up primary key object
            PiezaPedidaPK piezaPedidaPK = new PiezaPedidaPK();
            piezaPedidaPK.setIdPedidousuario(orderId);
            piezaPedidaPK.setIdPieza(idPieza);

            // create ordered item using PK object
            PiezaPedida itemPedido = new PiezaPedida();
            itemPedido.setId(piezaPedidaPK);

            // set quantity
            itemPedido.setCantidad(new BigDecimal(scItem.getCantidad()));

            //em.persist(itemPedido);
            piezaPedidaFacade.create(itemPedido);
        }
    }

}

The problem is in the method placeOrder(Usuario usuario, ShoppingCart cart) when I try to get the PK of the persisted PedidoUsuario.
For it I use an EJB that implements a StoredProcedureCall class. Why? The reason why is that if I use JPQL, being the PK type of sequence,
it returns a wrong PK. So I guessed it could be resolved attacking the database directly.

Here is the EJB,

@Stateless
public class ObtenerMaxIdPedidoUsuario implements Serializable {

    private static final long serialVersionUID = 1L;
   
    /**
     * Default constructor.
     */
    public ObtenerMaxIdPedidoUsuario() {
        // TODO Auto-generated constructor stub
    }
   
    public long ObtenerMaxId() throws Exception {

        final Logger logger = Logger.getLogger("ObtenerMaxIdPedidoUsuario");
       
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("AlmacenJPA");
        EntityManager em = emf.createEntityManager();
       
        try {
       
            JpaEntityManager jpaEntityManager = JpaHelper.getEntityManager(em);
            Session session = jpaEntityManager.getActiveSession();
            StoredProcedureCall call = new StoredProcedureCall();
            call.setProcedureName("ALMACEN.OBTENER_MAX_ID_PEDIDO_USUARIO");
            call.addNamedOutputArgument("RESULT");
                       
            ValueReadQuery query = new ValueReadQuery();
            query.setCall(call);
           
            return (Long)session.executeQuery(query);
           
        } catch (Exception ex) {
            logger.severe("ERROR: " + ex.getMessage());
            throw ex;
        }
    }

}

being the Oracle SP as follows,

CREATE OR REPLACE PROCEDURE ALMACEN.OBTENER_MAX_ID_PEDIDO_USUARIO  (result OUT NUMBER)
IS
BEGIN
  SELECT MAX(ID_PEDIDOUSUARIO) INTO result
  FROM PEDIDO_USUARIO;
  EXCEPTION
  WHEN NO_DATA_FOUND THEN
    result := 0;
END;
/

But it fails. The EJB method ObtenerMaxId() returns a NullPointerException.

Maybe I am wrong in the code of the SP or maybe in the EJBs, I do not know.

Please help.


Back to the top