Anotaciones
en EJB 3.0
Contenidos
API de Persistencia: EntityManager
Anotaciones
de un Bean de Sesión
Anotaciones
de un Bean de Entidad
Mé;todos del ciclo de vida de una Entidad
Anotaciones de un Bean Manejador de Mensajes
Anotaciones comunes a los Beans de Sesión y Beans
Manejadores de Mensajes
Aunque sigue habiendo
muchos escépticos (y no es para menos) parece que por fin tenemos una versión de
EJBs que nos aporta muchas cosas buenas sin hacernos la vida imposible. Con esta
nueva versión se ha intentado facilitar todas las partes que se complicaban en
versiones anteriores (descriptores de despliegue interminables, obligación de
implementar interfaces, obligación de implementar métodos que nunca se utilizan
…).
Son muchas las mejoras
que se han incluido en la versión 3.0 de los EJBs pero una de las más
importantes es la utilización de anotaciones. Mediante las anotaciones se define
la seguridad, transaccionalidad, persistencia, mapeo objeto-relacional, se
obtienen objetos mediante inyección, etc.
API de Persistencia: EntityManager
Primero veremos algunas partes importantes de la API, como la interfaz
EntityManager. Esta interfaz
es en la que se apoya la API de persistencia y la que se encarga del mapeo entre una
tabla relacional y su objeto Java. Funcionalmente es similar a la clase Session de Hibernate o a PersistenceManager de JDO. Proporciona
mé;todos para manejar la
persistencia de un Bean de Entidad, permite añadir, eliminar, actualizar y consultar así como manejar su ciclo de vida. Sus métodos má;s importantes son:
-
persist(Object entity) – almacena el objeto
entity en la base de datos. -
merge(T entity)
– actualiza las modificaciones en la entidad devolviendo la lista resultante. -
remove(Object entity)
– elima la entidad. -
find(Class<T> entity, Object primaryKey) – busca la entidad a través de su clave primaria. -
flush() – sincroniza las entidades con el contenido de la base de datos. -
refresh(Object entity) – refresca el estado de la entidad con su contenido en la base de datos. -
createQuery(String query) – Crea una query utilizando el lenguaje JPQL. -
createNativeQuery() - Crea una query utilizando el lenguaje SQL. -
isOpen() – Comprueba si está; abierto el EntityManager. -
close() - Cierra el EntityManager.
Podemos obtener una referencia al EntityManager a través de la anotación @PersistenceContext.
El contenedor de EJB nos proporciona el contexto de persistencia
mediante inyección por lo que no tendremos que preocuparnos de
su creación y destrucción.
@PersistenceContext
EntityManager entityManager;
Otra forma de obtener un EntityManager es a través de la factoría
EntityManagerFactory
con el nombre del contexto de persistencia configurado en el persistence.xml .
EntityManagerFactory emf = Persistence.createEntityManagerFactory(«TestPersistence«);
EntityManager em = emf.createEntityManager();
En el método createEntityManagerFactory de la clase Persistence se debe pasar el nombre del contexto definido en el persistence.xml .
Es
donde se definen los contextos de persistencia de la aplicación.
Se debe situar dentro del directorio META-INF.
<persistence>
<persistence-unit name=»TestPersistence«>
<jta-data-source>java:/AnotacionesEJB3DS</jta-data-source>
<properties>
<property name=»hibernate.dialect» value=»org.hibernate.dialect.MySQLDialect«/>
</properties>
</persistence-unit>
</persistence>
persistence-unit name:
Especifica un nombre
para el contexto persistente.
Si únicamente se especifica
uno, no habrá; que incluir su nombre cuando se recupere el EntityManager
(con la anotación @PersistenceContext o @PersistenceUnit).
jta-data-source, non-jta-data-source:
Nombre
JNDI del DataSource. También debemos crear un DataSource para la conexión a la base de datos:
<datasources>
<local-tx-datasource>
<jndi-name>AnotacionesEJB3DS</jndi-name>
<connection-url>jdbc:mysql://localhost:3306/AnotacionesEJB3DS</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>username</user-name>
<password>password</password>
</local-tx-datasource>
</datasources>
properties:
Se especifica
el tipo de base de datos a utilizar.
Engloba dos aspectos: la relación
entre el objeto Entidad y su contexto a persistir y por otro lado la
sincronización de su estado con la base de datos. Para realizar
estas operaciones la Entidad puede encontrarse en cualquiera de estos
cuatro estados:
-
new –
Nueva instancia de la Entidad en memoria sin que aún le sea
asignado su contexto persistente almacenado en la tabla de la base de
datos. -
managed –
La Entidad dispone de contenido asociado con el de la tabla de la base
de datos debido a que se utilizó el método
persist().
Los cambios que se produzcan en la Entidad se podrá;n sincronizar
con los de la base de datos llamando al método
flush(). -
detached – La Entidad se ha quedado sin su contenido persistente. Es necesario utilizar el método
merge() para actualizarla. -
removed – Estado después de llamarse al método
remove() y el contenido de la Entidad será; eliminado de la base de datos.
Una
anotación o metadato proporciona un recurso adicional al
elemento de código al que va asociado en el momento de su
compilación. Cuando la JVM ejecuta la clase busca estos
metadatos y determina el comportamiento a seguir con el
có;digo
al que va unido la anotación.
Anotaciones
de un Bean de Sesión
@Stateful:
Indica que el Bean de Sesión es con estado.
-
name
– por defecto el nombre de la clase pero se puede especificar otra
diferente. -
mappedName –
si se quiere que el contenedor maneje el objeto de manera
específica. Si incluimos esta opción nuestra
aplicación puede que no sea portable y no funcione en otro
servidor de aplicaciones. -
description –
descripción de la anotación.
@Stateless:
Indica que el Bean de Sesión es sin estado.
-
mismos atributos
que @Stateful
@Init:
Especifica que el método se corresponde con un
método
create de un EJBHome o EJBLocalHome de EJB 2.1. Sólo se
podrá; llamar una única vez a este
método.
-
value
– indica el nombre del correspondiente método create de la
interfaz home adaptada. Sólo se debe utilizar cuando se
utiliza
el bean anotado con un bean con estado de la especificación
2.1
o anterior y que disponga de má;s de un método
create.
@Remove:
Indica que el contenedor debe llamar al método cuando quiera
destruir la instancia del Bean.
-
retainIfException –
indica si el Bean debe mantenerse activo si se produce una
excepción. Por defecto a false.
@Local:
Indica que la interfaz es local.
@Remote:
Indica que la interfaz es remota.
@PostActivate:
Invocado después de que el Bean sea activado por el
contenedor.
@PrePassivate: Invocado antes de que el Bean
esté en estado passivate.
Anotaciones
de un Bean de Entidad
@Entity:
Indica que es un Bean de Entidad.
-
name – por defecto el nombre de la clase
pero se puede especificar otra diferente.
Métodos del ciclo de vida de una Entidad
@EntityListeners:
Se pueden definir clases oyentes (listeners)
con métodos de
ciclo de vida de una entidad. Para hacer referencia a un
listener se debe incluir esta anotación
seguido entre
paréntesis de la clase: @Entity
Listeners(MyListener.class)
@ExcludeSuperclassListeners:
Indica que ningún listener de la
superclase será; invocado
por la entidad ni por ninguna de sus subclases.
@ExcludeDefaultListeners:
Indica que ningún listener por defecto
será;
invocado por esta clase ni por ninguna de sus subclases.
@PrePersist:
El método se llamará; justo antes de la
persistencia del
objeto. Podría ser necesario para asignarle la clave
primaria a la entidad a persistir
en base de datos.
@PostPersist:
El método se llamará; después de la
persistencia
del objeto.
@PreRemove:
El método se llamará; antes de que la
entidad sea eliminada.
@PostRemove:
El método se llamará; después de
eliminar la entidad de la base de datos.
@PreUpdate:
El método se llamará; antes de que una entidad sea
actualizada en base de datos.
@PostUpdate:
El método se llamará; después de que la
entidad sea actualizada.
@PostLoad:
El método se llamará; después de que
los campos
de la entidad sean cargados con los valores de su entidad
correspondiente de la base de datos. Se suele utilizar para
inicializar valores no persistidos.
@FlushMode:
Modo en que se ejecuta la transacción: FlushModeType.AUTO
(por defecto) y FlushModeType.COMMIT.
@NamedQuery:
Especifica el nombre del objeto query utilizado junto a EntityManager.
-
name
– nombre del objeto query. -
query – especifica
la query a la base de datos mediante lenguaje Java Persistence Query
Language (JPQL)
@NamedQueries:
Especifica varias queries como la anterior.
@NamedNativeQuery:
Especifica el nombre de una query SQL normal.
-
name
– nombre del objeto query. -
query – especifica
la query a la base de datos. -
resultClass – clase
del objeto resultado de la ejecución de la query. -
resultSetMapping –
nombre del SQLResultSetMapping
definido (se explica má;s abajo).
@NamedNaviteQueries:
Especifica varias queries SQL.
@SQLResultSetMapping:
Permite recoger el resultado de una query SQL.
-
name
– nombre del objeto asignado al mapeo. -
EntityResult[] entities() –
entidades especificadas para el mapeo de los datos. -
ColumnResult[] columns() – columnas de la tabla para el mapeo
de los datos.
@NamedNativeQuery(name=»nativeResult», query=»SELECT NOMBRE,APELLIDOS FROM USUARIOS WHERE
USUARIO_ID= 123″,
resultSetMapping = «usuarioNamedMapping«)
@SqlResultSetMapping(name=»usuarioNamedMapping«,
entities = {
@EntityResult(entityClass = com.autentia.entidades.Usuario.class,
fields = {
@ColumnResult(name=»usuarioId», column=»USUARIO_ID»),
@ColumnResult(name=»nombre», column=»NOMBRE»),
@ColumnResult(name=»apellidos», column=»APELLIDOS»)})})
@PersistenceContext:
Objeto de la clase EntityManager que nos proporciona todo lo que
necesitamos para manejar la persistencia.
-
name
– nombre del objeto utilizado para la persistencia en caso de ser diferente al de la clase donde se incluye la anotación. -
unitName – identifica la unidad de la persistencia usada en el bean en caso de que hubiera má;s de una. -
type – tipo de persistencia, TRANSACTION (por defecto) | EXTENDED.
@PersistenceContexts:
Define varios contextos de persistencia.
@PersistenceUnit:
Indica la dependencia de una EntityManagerFactory definida en el
archivo persistence.xml.
-
name
– nombre del objeto utilizado para la persistencia en caso de ser diferente al de la clase donde se incluye la anotación. -
unitName – identifica la unidad de la persistencia usada en el bean en caso de que hubiera má;s de una.
Existen
varios tipos de relaciones entre tablas de una base de datos: 1:1, 1:N,
N:1 y N:M (en la implementación se considera lo mismo 0 que 1). Cuando
se establecen relaciones entre entidades (1:N, N:M), se utilizan
colecciones para mapear los campos de la entidad relacionada
(por ejemplo si un banco tiene N cuentas, en la entidad que mapeará; la
tabla banco se deberá; crear una colección de cuentas para almacenar los
valores de la relación.
Las
relaciones entre entidades pueden ser unidireccionales o
bidireccionales. En las unidireccionales únicamente se puede acceder
desde una entidad a otra, no al revés. En las bidireccionales la
relación se da en los dos sentidos por lo que desde cualquiera de las
dos entidades se accede a la otra.
Hay que tener especial cuidado
en establecer los lados de una relación ya que existen dos: «owning
side» (lado propietario) e «inverse side» (lado inverso). El lado propietario
es el que tiene la clave forá;nea de la relación y el inverso el que la
proporciona. Únicamente las relaciones bidireccionales poseen los dos
lados. Si la relación es 1:N el lado propietario
es el lado que contiene la N. En las relaciones N:M ambos pueden tener
el lado propietario y en las relaciones 1:1 la entidad que contiene la
clave forá;nea es la que se considera que tiene el «owning side».
@Table:
Especifica la tabla principal relacionada con la entidad.
-
name
– nombre de la tabla, por defecto el de la entidad si no se
especifica. -
catalog
– nombre del catá;logo. -
schema
– nombre del esquema. -
uniqueConstraints
– constrains entre tablas relacionadas con la
anotación @Column
y @JoinColumn
@SecondaryTable:
Especifica una tabla secundaria relacionada con el Bean de entidad si
éste englobara a má;s de una. Tiene los mismos
atributos que
@Table
@SecondaryTables:
Indica otras tablas asociadas a la entidad.
@UniqueConstraints:
Especifica que una única restricción se incluya
para la
tabla principal y la secundaria.
@Column:
Especifica una columna de la tabla a mapear con un campo de la entidad.
-
name
– nombre de la columna. -
unique
– si el campo tiene un único valor. -
nullable
– si permite nulos. -
insertable
– si la columna se incluirá; en la sentencia INSERT generada. -
updatable
– si la columna se incluirá; en la sentencia UPDATE generada. -
table
– nombre de la tabla que contiene la columna. -
length
– longitud de la columna. -
precision
– número de dígitos decimales. -
scale
– escala decimal.
@JoinColumn:
Especifica una campo de la tabla que es foreign key de otra tabla definiendo la relación del lado propietario.
-
name
– nombre de la columna de la foreign key. -
referenced
– nombre de la columna referencia. -
unique
– si el campo tiene un único valor. -
nullable
– si permite nulos. -
insertable
– si la columna se incluirá; en la sentencia INSERT generada. -
updatable
– si la columna se incluirá; en la sentencia UPDATE generada. -
table
– nombre de la tabla que contiene la columna.
@JoinColumns:
Anotación para agrupar
varias JoinColumn.
@Id:
Indica la clave primaria de la tabla.
@GeneratedValue:
Asociado con la clave primaria, indica que ésta se debe
generar por ejemplo con una secuencia de la base de datos.
-
strategy
– estrategia a seguir para la generación de la
clave: AUTO
(valor por defecto, el
contenedor decide la estrategia en función de la base de datos),
IDENTITY (utiliza un contador, ej: MySQL), SEQUENCE (utiliza una
secuencia, ej: Oracle, PostgreSQL) y
TABLE (utiliza una tabla de identificadores). -
generator
– forma en la que general la clave.
@SequenceGenerator:
Define
un generador de claves primarias utilizado junto con la
anotación
@GeneratedValue.
Se
debe especificar la secuencia en la entidad junto a la clave
primaria.
-
name
– nombre del generador de la clave. -
sequence
– nombre de la secuencia de la base de datos del que se va a
obtener la clave. -
initialValue
– valor inicial de la secuencia. -
allocationSize
– cantidad a incrementar de la secuencia cuando se llegue al
má;ximo.
@TableGenerator:
Define una tabla de claves primarias generadas.
Se debe especificar en la
anotación
@GeneratedValue con
strategy = GenerationType.TABLE.
-
name
– nombre de la secuencia. -
table
– nombre de la tabla que guarda los valores generados. -
catalog
– catalog de la tabla. -
schema
– esquema de la tabla. -
pkColumn
Name() – nombre de la clave primaria de la tabla. -
valueColumn
Name() – nombre de la columna que guarda el
último valor
generado. -
pkColumn
Value() – valor de la clave primaria. -
initialValue
– valor inicial de la secuencia. -
allocationSize
– cantidad a incrementar de la secuencia. -
uniqueConstraints
- constrains entre tablas relacionadas.
@AttributeOverride:
Indica que sobrescriba el campo con el de la base de datos
asociado.
-
name
– nombre del campo -
column
– columna del campo
@AttributeOverrides:
Mapeo de varios campos.
@EmbeddedId:
Se utiliza para formar la clave primaria con múltiples
campos.
@IdClass:
Se aplica en la clase entidad para especificar una
composición
de la clave primaria mapeada a varios campos o propiedades de la
entidad.
@Transient:
Indica que el campo no se debe persistir.
@Version:
Se utiliza a la hora de persistir la entidad en base de datos para identificar las entidades según su versión. Se
actualiza automá;ticamente cuando el objeto es mapeado en la
base de datos.
@Basic:
Mapeo por defecto para tipos bá;sicos: tipos primitivos,
wrappers de los tipos primitivos, String, BigInteger, BigDecimal,
Date, Calendar, Time, Timestamp, byte[], Byte[], char[], Character[],
enumerados y cualquier otra clase serializable.
-
fetch
– determina la forma en que se cargan los datos (relaciones entre tablas):
FetchType.LAZY
(carga de la entidad únicamente cuando se utiliza), FetchType.EAGER
(carga de todas las entidades relacionadas con ella). -
optional – si permite que el campo sea nulo. Por defecto true.
En el ejemplo de arriba:
FechType.EAGER
– En el momento de acceder a la tabla ‘Empleado’ también se
consultan las tablas Cuenta y Contrato y las
entidades que a su vez contuvieran éstas ya que está;n
relacionadas
FechType.LAZY
– En el momento de acceder a la tabla Empleado únicamente se
carga su contenido y en el momento de necesitar alguno de los campos
idCuenta o idContrato, es en ese momento cuando se
accede a la tabla correspondiente.
@OneToOne:
(1:1) Indica que un campo está; en relación con otro
(ej: dentro de una empresa, un
empleado tiene un contrato de trabajo).
-
cascade
– forma en que se deben actualizar los campos: ALL, PERSIST,
MERGE, REMOVE y REFRESH. -
fetch
– determina la forma en que se cargan los datos: FetchType.LAZY
(carga de la entidad únicamente cuando se utiliza), FetchType.EAGER
(carga de todas las entidades relacionadas con ella). -
optional
– si la asociación es opcional. -
mappedBy
– el campo que posee la relación,
únicamente se
especifica en un lado de la relación.
@ManyToOne:
(N:1) Indica que un campo está; asociado con varios campos de otra
entidad (ej: las cuentas que posee un banco o los empleados que pertenecen a un departamento).
-
cascade,
fetch y optional
– igual que la anterior
anotación.
@OneToMany:
(1:N) Asocia varios campos con uno (ej: varios departamentos de una
empresa).
-
cascade,
fetch y optional
– igual que la anterior
anotación. -
mappedBy
– El campo que posee la relación. Es obligatorio
que la
relación sea unidireccional.
@ManyToMany:
(N:M) Asociación de varios campos con otros con multiplicidad muchos-a-muchos
(ej: relaciones entre empresas).
- cascade, fetch y mappedBy – igual que la anterior
anotación.
@Lob:
Se utiliza junto con la anotación @Basic
para indicar que un campo se debe persistir como un campo de texto largo si
la base de datos soporta este tipo.
@Temporal:
Se utiliza junto con la anotación @Basic
para especificar que un campo fecha debe guardarse con el tipo
java.util.Date o java.util.Calendar. Si no se especificara ninguno de
estos por defecto se utiliza java.util.Timestamp.
@Enumerated:
Se utiliza junto con la anotación @Basic
e indica
que el
campo es un tipo enumerado (STRING), por defecto ORDINAL.
@JoinTable:
Se utiliza en el mapeo de una relación
ManyToMany o en una
relación unidireccional OneToMany.
-
name
– nombre de la tabla join a donde enviar la foreing key. -
catalog
– catalog de la tabla. -
schema
– esquema de la tabla. -
joinColumns
– columna de la foreign key de la tabla join que referencia a
la
tabla primaria de la entidad que posee la asociación
(sólo
en un lado de la relación). -
inverseJoinColumns
– columnas de la foreign key de la tabla join que referencia
a la
tabla primaria de la entidad que no posee (lado inverso de la
relación) -
uniqueConstraints
– constraints de la tabla.
@MapKey:
Especifica la clave de una clase de tipo java.util.Map
@OrderBy:
Indica el orden de los elementos de una colección por un
item
específico de forma ascendente o descendente.
@Inheritance:
Define la forma de herencia de una jerarquía de clases
entidad, es decir la relación entre las tablas relacionales
con los Beans de entidad.
-
strategy
– SINGLE_TABLE que indica una única tabla para
varias entidades (por defecto), JOINED, TABLED_PER_CLASS
@DiscriminatorColumn:
Relacionada con
@Inheritance cuando
ésta define la estrategia SINGLE_TABLE. Define la columna
común de las entidades que forman la jerarquía..
-
name
– nombre de la columna,
por defecto DTYPE -
DiscriminatorType
– Tipo de la columna que se utiliza para identificar la
entidad. Por defecto DiscriminatorType.STRING. -
length
– longitud de la columna, por defecto 31.
@DiscriminatorValue:
Especifica el valor a persistir en la columna que identifica el tipo de
entidad a guardar en la tabla.
-
value
– indica que el valor utilizado para diferenciar una clase de
la
jerarquía.
Un
ejemplo de esto se muestra en el siguiente diagrama. Se declaran tres
Beans de entidad para una única entidad de base de datos. A
la
hora de persistir la entidad tenemos que el campo TIPO de la tabla
MASCOTA hace referencia a varios tipos (PERRO, GATO).
utiliza la anotación @DiscriminatorColumn
que nos indica el campo que es común en las dos entidades
pero con diferente valor. Este valor se especifica en @DiscriminatorValue.
Especifica la clave primaria de la columna que es clave extranjera de
otra entidad.
-
name
– nombre de la clave primaria -
referenced
– nombre de la columna
@PrimaryKeyJoinColumns:
Agrupación de varias claves iguales que la anterior.
@Embeddable:
Con esta anotación podemos especificar en la propia entidad
un
objeto embebido de una entidad diferente.
@Embedded:
Especifica un campo persistente de una entidad especificado como
campo embebido de otra entidad mediante la anotación
@Embeddable.
@MappedSuperclass:
Asigna la información mapeada a la superclase de la entidad.
Anotaciones de un Bean Manejador de Mensajes
@MessageDriven:
Indica que la clase es un Bean Manejador de Mensajes.
-
name
– por defecto el nombre de la clase pero
se puede especificar otra diferente. -
messageListenerInterface
– especifica la interfaz del Bean message listener.
Obligatorio si el Bean no implementa una interfaz message
listener o implementa má;s de una distinta a Serializable, Externalizable o
alguna de las incluidas en el paquete javax.ejb. -
activationConfig – otras opciones de configuración para JMS. Equivalentes a las que se introducían en la etiqueta <activation-config-property> del descriptor de despliegue en EJB 2.1 (destinationType, messageSelector, acknowledgment, durability). -
mappedName – si
se quiere que el contenedor maneje el objeto indicado de manera
específica. -
description
– descripción del Bean.
Anotaciones comunes a los Beans de Sesión y Beans
Manejadores de Mensajes
@Timeout:
Asigna un tiempo de ejecución a un método.
@ApplicationException:
Excepción a enviar al cliente cuando se produzca.
@TransactionManagment:
Especifica quién va a manejar la transacción: el
contenedor (TransactionManagmentType.CONTAINER) o el Bean (TransactionManagmentType.BEAN).
@TransactionAttribute:
Especifica el método de negocio invocado por el
contexto
de la transacción únicamente si es manejada por
el
contenedor. (TransactionAttributeType.REQUIRED (por defecto)
|
MANDATORY | REQUIRES_NEW | SUPPORTS | NOT_SUPPORTED | NEVER.
Los Interceptores son
métodos invocados automá;ticamente al
invocar a los métodos de negocio de un Bean
@Interceptors: Interceptores asociados
con el Bean. Entre paréntesis y llaves se indican
las clases donde se declaran.
@AroundInvoke:
Designado a un método de un Interceptor. Se
llamará;
a este método siempre que se llame a un método
anotado
con @Interceptors
({NombreInterceptor.class}) donde NombreInterceptor es la clase donde se declara el
método anotado con @AroundInvoke
@ExcludeDefaultInterceptors:
Se utiliza para excluir la invocación de un Interceptor en caso de que para un
Bean de negocio en concreto no queramos que se llame a
ningún metodo de los Interceptores.
@ExcludeClassInterceptors:
Excluye
la invocación de los Interceptores a nivel de clase.
@PostConstruct:
Invocado después de que el Bean sea creado
(después de hacerse las inyecciones de dependencias).
@PreDestroy:
Invocado después de que el Bean sea destruido del pool del
contenedor.
@DeclareRoles:
Especifica los roles de seguridad asociados con el Bean.
@RolesAllowed: Sólo
los roles declarados en esta anotación podrá;n
invocar el
método. Se pueden especificar los roles permitidos
a nivel
de clase o a nivel de método.
@PermitAll:
Permite la invocación por todos los roles definidos. Se
puede especificar a nivel de clase o a nivel de método.
@DenyAll: Bloquea
a todos los roles de manera que ninguno podrá; llamarlo.
Únicamente a nivel de método.
@RunAs: Se aplica
a nivel de clase e indica el rol con el que se ejecuta el Bean: @RunAs(«admins»)
El
concepto de inyección de dependencias se refiere a la separación entre la
construcción de un objeto a la de su utilización. El contenedor
es el encargado de la creación y destrucción del objeto que
es devuelto a quien lo solicita.
@EJB:
Mediante esta anotación el contenedor asignará; la referencia del
EJB indicado.
-
name
– nombre del recurso. -
BeanIntefface
– tipo de la interfaz de referencia, por defecto Object.class -
BeanName
– nombre del Bean especificado con el atributo name en
caso de que varios Beans implementen la misma interfaz . -
mappedName
– si
se quiere que el contenedor maneje el objeto indicado de manera
específica. -
description
– descripción de la anotación para la
inyección de dependencia.
@EJBs: Igual que
la anotación anterior pero especificando má;s de
un EJB.
@Resource:
Referencia de un recurso específico.
-
name
– nombre del recurso. -
type
– tipo del objeto (Object.class por defecto) -
authenticationType
– especifica dónde se debe realizar el proceso de
autenticación,
por defecto AuthSenticationType.CONTAINER -
shareable
– indica si el objeto se comparte, por defecto true. -
mappedName
– si
se quiere que el contenedor maneje el objeto indicado de manera
específica. -
description
– descripción de la anotación para la
inyección de dependencia.
@Resources:
Referencia múltiples recursos en la misma
anotación.
Bueno parece que todo esto está muy bien, parece fácil pero ¿realmente lo es?.
La verdad es que sí, ahora programar EJBs es dé lo más sencillo e intuitivo.
Basta con crear unos cuantos POJOs añadiéndoles determinadas anotaciones para
especificar lo que queremos hacer.
El
ejemplo lo seguiremos sobre la entidad Empleado que veíamos en el diagrama
anterior. Mediante los beans podremos dar de alta/baja y listar los empleados.
Todo esto sin escribir una sola línea de código SQL y sin complicarnos la vida.
EmpleadoEB
/* Indica
/* Tabla a
@Table(name
/* Los
} |
Ahora creamos dos Beans de Sesión sin estado. El primero es el EmpleadoMgrBean
que hace de fachada al segundo, el EmpleadoDAOBean que contiene el contexto de
persistencia. Cada Bean de Sesión deberá implementar su interfaz local
correspondiente que declara los métodos utilizados en el Bean. Los interfaces
serán locales ya que no será necesario invocar a los EJBs desde una máquina
remota. Si se quisiera invocar al Bean desde remoto habrá que crear una interfaz
igual a la local y anotarla con @Remote.
EmpleadoMgrLocal
@Local
}
|
EmpleadoMgrBean
/* Indica @Stateless
} |
EmpleadoDAOLocal
} |
EmpleadoDAOBean
/* Indica
/*
} |
Para que esto haga
algo habría que crearse una aplicación de prueba e invocar por JNDI al EJB.
Context
}
}
|
Links de interés
http://java.sun.com/products/ejb/reference/techart/index.html
http://docs.jboss.org/ejb3/app-server/tutorial/
https://blogs.oracle.com/enterprisetechtips/ejb-30-compatibility-and-migration
Puede que la nueva versión de EJBs no sea del agrado de todos ya que existen
otras posibilidades que gozan de mayor aceptación hoy en día como Spring, pero
hay que reconocer que se ha hecho mucho esfuerzo por mejorar la API y merece la
pena tenerla en cuenta.
Desde Autentia creemos en la difusión del
conocimiento y el software libre, como aportación hemos liberado nuestra
herramienta de gestión de empresas. Puedes probarla desde
http://tntconcept.adictosaltrabajo.com o descargártela desde
aquí
Hola Juan Alonso.
Muy buen tutorial y excelente para empezar…
Pero dime una cosa? a todo eso no le estaría faltando los archivos de configuración del jboss y del ejb mismo. Los archivos XML, por que yo traté de hacer tal cual explicaste, pero por lo que me doy cuenta todavia falta la parte de configuración.
Saludos.
http://www.marcosjara.com
Hola, muy bueno, pero no logro hacer funcionar el ejemplo, puedes subir los ficheros .xml de configuración por favor?
Saludos.
Hola Juan Alfonso,
Yo de nuevo y espero que esta vez tengas tiempo para responder.
Trataré de exponer a continuación mi pregunta resumiendo el concepto de la implementación que deseo realizar.
Bien,
Tengo un proyecto EJB de Ventas de Artículos que está funcionando perfectamente y controla super bien la parte del inventario, pero lo que no controla es la
parte del pago por las mercaderías, por ej.: si es al contado o se generan cuentas a pagar, etc., tampoco controla la facturación.
Lo que deseo es incorporar dichas funcionalidades nuevas, formas de pago y facturación al EJB de sesión (lógica existente) del método que guarda la venta,
sin tocar ún sólo código de la clase sesion ben original.
Es decir, deseo incorporarle esas funcionalidades por aspectos (AOP).
He leido mucho y he encontrado que la programación por Aspectos para EJBs se realizan mediante interceptores y que segun la teoría, ésta es realizada sin
tocar el código original de sesión en mi caso (justo lo que necesito), sin embargo al buscar implementaciones, todas las que encontré necesitan que SI se
modifique el código original, justamente para adicionar el annotation de @Interceptor arriba del método de la sesión donde se guarda la venta.
Esto me serviría perfectamente si pudiera vincular el @Interceptor al método de la clase sesion bean desde fuera de él, es decir desde alguna otra ubicación.
Por ejemplo que tal dentro del mismo interceptor que quiero crear.
Además, qué pasa si sólo tengo el código binario de la clase Sesion Bean que posee el método que guarda la Venta venta y quiero implementar dicha
funcionalidad?, existe alguna otra forma de adicionar dicho interceptor?, por algún otro lado? desde fuera del Sesion EJB mismo.
Saludos.
Super chevere tu aporte pero podrias indicar cuando usar la anotacion @EJBs, que uso tiene y bajo que escenarios seria correcto hacer uso de la misma, y podrias por favor profundizar en la diferencia entre @EJB y @EJBs por favor, gracias