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.