Pautas asociadas al uso de EJB3
- Área: Capa de Negocio de Aplicaciones Java
- Tipo de pauta: Directriz
- Carácter de la pauta: Obligatoria
Se deben tener en cuenta las siguientes pautas para el desarrollo de aplicaciones basadas en EJB3.
Pautas
Elección correcta de la estrategia de herencia
EJB3 soporta tres tipos de estrategia de herencia en la vinculación. Cada una con sus ventajas y desventajas, pero la estrategia basada en tablas simples (single-table strategy) es la que probablemente ofrezca un mejor rendimiento. Esto es debido a que todas las entidades se almacenan en una tabla simple y los "JOINs" entre tablas están permitidos. Lo recomendable es crear una tabla y discriminarlas de forma eficiente. Una columna discriminadora es aquella que contiene un valor único de un tipo de objeto en una fila de la tabla. Por ejemplo, la tabla se discrimina por el tipo de usuario:
@Table(name = "USERS")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "USER_TYPE",discriminatorType = DiscriminatorType.STRING, length = 1)
public class User ...
@Entity
@DiscriminatorValue(value = "S")
public class Seller extends User ...
@Entity
@DiscriminatorValue(value ="B")
public class Bidder extends User
Usar consultas con nombre
En lugar de usar consultas dinámicas, asegúrese de que utiliza consultas con nombre en su aplicaciones. Una consulta con nombre se prepara una vez y puede ser reutilizada por el proveedor de persistencia de forma eficiente. Además, el SQL generado puede ser almacenado en caché. Usted puede convertir la consulta anterior a una consulta con nombre como este:
@NamedQuery(
name = "findCategoryByName",
query = "SELECT c FROM Category c WHERE c.categoryName = ?1")
Uso de la interfaz remota y de la interfaz local en los beans de sesión
Solo se debe utilizar la interfaz remota cuando se realicen invocaciones desde diferentes JVM
EJB 3 no sólo proporciona la capacidad de invocar los componentes de forma remota, sino también le autoriza para construir componentes ligeros que se pueden implementar y ejecutar localmente con los módulos de su presentación. Si sus clientes y los componentes EJB están colocados juntos, entonces debe asegurarse de que no se debe marcar con su interfaz la anotación @Remote. La interfaz remota utiliza una costosa llamada RMI incluso si los clientes están en la misma JVM.
Si su arquitectura tiene una condición por la cual la aplicación cliente tiene que ejecutarse en una máquina diferente JavaVirtual (JVM) de la que se utiliza para ejecutar los beans de sesión en un contenedor EJB, entonces necesita utilizar la interfaz remota. La JVM distinta, puede ubicarse en la misma máquina física o en máquinas separadas. Si su arquitectura de aplicaciones va a utilizar la misma JVM, tanto para la aplicación de cliente y los beans de sesión, se debe utilizar la interfaz local.
- La anotación @Remote puede utilizarse para referirse a la interfaz de negocio a distancia.
- La anotación @Local puede ser usado para denotar la interfaz de negocio local.
Usar los beans de sesión con estado solo cuando sea necesario
Existe una tendencia a abusar de los beans de sesión con estado, que hace que los desarrolladores queden decepcionados con su rendimiento. La mayoría de las aplicaciones empresariales no tienen estado por naturaleza, por lo que se debe determinar si se necesitan beans de sesión con estado . Los beans de sesión sin estado ofrecen un desempeño mucho mejor que los beans de sesión con estado, ya que no están obligados a administrar el estado. Por lo tanto, es recomendable solo usar los beans de sesión con estado si su uso es justificado.
Uso correcto de las transacciones
En el caso de de utilizar CMP es recomendable estudiar sin son necesarias todas las transacciones, prestando especial atención a los atributos de transacción de cada método de negocio.
La gestión de transacciones es un asunto costoso. Es recomendable verificar que cada método EJB realmente necesita una transacción. Si está utilizando el manejo de transacciones por CMT (por defecto), el contenedor inicia una transacción porque el valor predeterminado del atributo de transacciones es "Required" . Para los métodos que no requieren de una transacción, debe explícitamente deshabilitar las transacciones estableciendo el tipo de transacción a NOT_SUPPORTED de la siguiente manera:
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public List<Item> findMostPopularItems() {
...
}
Utilizar un método Remove en los beans de sesión con estado
Se debe destruir una instancia de bean de sesión con estado usando la anotación @Remove cuando concluye la conversación. Cualquier método de negocio puede ser anotado con @Remove para que una vez finalizada con éxito de ese método de negocio, la instancia del bean será destruido. Se puede ver en confirmOrder:
@Remove
public Long confirmOrder() {
}
Si no se eliminan las instancias del bean con estado cuando ya no se necesitan, es muy probable que el número de instancias del bean inactivas crezca forzando a la continua activación/desactivación del contenedor. Además de esta anotación, la mayoría de los contenedores proporcionan un tiempo de terminación para destruir una instancia de un bean. Este tiempo de espera (time out) es útil para mantener el número de instancias del bean en un número manejable. Es recomendable utilizar este tiempo de terminación.
No realizar inyecciones de un bean con estado sobre un objeto sin estado
No se debe inyectar un bean de sesión con estado en un objeto sin estado, porque un bean de sesión con estado puede estar compartido por múltiples clientes de forma concurrente. Para estos casos es recomendable usar JNDI.
Esto se debe a que cuando se utiliza la inyección de dependencias, el contenedor inyecta un nuevo bean de sesión con estado en el bean de sesión sin estado, el mismo bean de sesión con estado no puede ser inyectado en todos los beans de sesión sin estado. Si se hace uso de JNDI, la referencia a un bean de sesión con estado puede ser obtenida e inyectada en todos los beans de sesión sin estado. El mismo bean con estado podría ser utilizado.