Java EE7 consiste en un conjunto de definiciones de “bean”:
Para poder deshacerme del caos en mi mente, estudio varios artículos sobre “cuándo usar qué tipo de frijol”. Uno de los pros de EJB parece ser que solo soportan transacciones declarativas manejadas por contenedor (las famosas anotaciones de transacciones). No estoy seguro, sin embargo, si esto es correcto. ¿Alguien puede aprobar esto?
Mientras tanto, se me ocurrió una aplicación de demostración simple para comprobar si esto era cierto. Acabo de definir un bean CDI ( no un EJB, no tiene anotaciones de nivel de clase) de la siguiente manera, basado en este fragmento:
public class CdiBean { @Resource TransactionSynchronizationRegistry tsr; @Transactional(Transactional.TxType.REQUIRED) public boolean isTransactional() { return tsr.getTransactionStatus() == Status.STATUS_ACTIVE; } }
Ahora, el resultado en GlassFish 4.0 es que este método realmente devuelve verdadero, lo cual, según mis investigaciones, no está funcionando como se esperaba . Esperaba que el contenedor ignorara la anotación @Transactional en un método de bean CDI, o incluso arrojara una excepción. Utilizo un servidor GlassFish 4 recién instalado, por lo que no hay interferencias.
Entonces mi pregunta es realmente:
(Por cierto: alguien describió un problema similar aquí , pero su solución no se aplica a mi caso.
Hasta Java EE 7, solo EJB era transaccional y la anotación @Transactional
no existía.
Desde Java EE 7 y JTA 1.2 puede usar el interceptor transaccional en CDI con la anotación @Transactional
.
Para responder a su pregunta sobre el mejor tipo de frijol a usar, la respuesta es CDI por defecto.
Los beans CDI son más livianos que EJB y admiten muchas características (incluido el ser EJB) y se activan de manera predeterminada (cuando agrega el archivo beans.xml
a su aplicación). Desde Java EE 6 @Inject
reemplaza @EJB
. Incluso si utiliza EJB remotos (característica que no existe en CDI), la mejor práctica sugiere que @EJB
una vez para inyectar EJB remoto y un productor de CDI para exponerlo como un frijol CDI
public class Resources { @EJB @Produces MyRemoteEJB ejb; }
Lo mismo se sugiere para los recursos de Java EE
public class Resources2 { @PersistenceContext @Produces EntityManager em; }
Estos productores serán utilizados más tarde
public class MyBean { @Inject MyRemoteEJB bean; @Inject EntityManager em; }
EJB sigue teniendo sentido para ciertos servicios que incluyen, como JMS o tratamiento asíncrono, pero los usará como CDI Bean.
El javadoc de Transactional dice:
La anotación javax.transaction.Transactional proporciona a la aplicación la capacidad de controlar declarativamente los límites de transacción en beans administrados CDI, así como las clases definidas como beans administrados por la especificación Java EE, en el nivel de clase y método donde las anotaciones de nivel de método anulan las de el nivel de clase.
Entonces, tus suposiciones son incorrectas. Los EJB, hasta Java EE 6, eran los únicos tipos de componentes para admitir transacciones declarativas. La anotación transaccional se ha introducido precisamente en Java EE 7 para hacer que los beans CDI gestionados no EJB sean transaccionales.