The sections that follow describe how to program the annotated EJB 3.0 class file:
The new EJB 3.0 programming model uses the
JDK 5.0 metadata annotations feature in which you create an annotated EJB 3.0 bean file and then use the WebLogic compile tool weblogic.appc
(or its Ant equivalent wlappc
) to compile the bean file into a Java class file and generate the associated EJB artifacts, such as the required EJB interfaces and deployment descriptors.
The annotated 3.0 bean file is the core of your EJB. It contains the Java code that determines how your EJB behaves. The 3.0 bean file is an ordinary Java class file that implements an EJB business interface that outlines the business methods of your EJB. You then annotate the bean file with JDK 5.0 metadata annotations to specify the shape and characteristics of the EJB, document your EJB, and provide special services such as enhanced business-level security or special business logic during runtime.
See Complete List of Metadata Annotations By Function for a breakdown of the annotations you can specify in a bean file, by function. These annotations include those described by the Enterprise JavaBeans 3.0 specification (JSR-220), as well as some described by the Common Annotations for the Java Platform (JSR-250). See EJB 3.0 Metadata Annotations Reference, for reference information about the annotations, listed in alphabetical order.
This topic is part of the iterative development procedure for creating an EJB 3.0, described in Iterative Development of Enterprise JavaBeans 3.0.
The requirements for programming the 3.0 bean class file are essentially the same as the 2.X requirements. This section briefly describes the basic mandatory requirements of the bean class, mostly for overview purposes, as well as changes in requirements between 2.X and 3.0.
See Programming WebLogic Enterprise JavaBeans for detailed information about the mandatory and optional requirements for programming the bean class.
The following bullets list the new 3.0 requirements for programming a bean class, as well as the 2.X requirements that no longer apply:
@javax.ejb.Stateless
@javax.ejb.Stateful
@javax.ejb.MessageDriven
@javax.ejb.Entity
Note: | Programming a 3.0 entity is discussed in a separate document. See Enterprise JavaBeans 3 Persistence in the BEA Kodo documentation. |
javax.ejb.SessionBean
, which means the bean no longer needs to implement the ejbXXX()
methods, such as ejbCreate()
, ejbPassivate()
, and so on.java.io.Serializable
.javax.ejb.MessageDrivenBean
.The following requirements are the same as in EJB 2.X and are provided only as a brief overview:
public
, must not be final
, and must not be abstract
. The class must be a top level class.public
constructor that takes no parameters. finalize()
method.javax.jms.MessageListener
interface.The method requirements have not changed since EJB 2.X and are provided in this section for a brief overview only.
The requirements for programming the session bean class’ methods (that implement the business interface methods) are as follows:
public
and must not be final
or static
.throws
clause may define arbitrary application exceptions.The requirements for programming the message-driven bean class’ methods are as follows:
The following procedure describes the typical basic steps when programming the 3.0 bean file for a EJB. The steps you follow depends, of course, on what your EJB does.
Refer to Simple Enterprise JavaBeans 3.0 Examples, for code examples of the topics discussed in the remaining sections.
javax.ejb
package, the interceptor annotations are in the javax.interceptor
package, the annotations to invoke a 3.0 entity are in the javax.persistence
package, and the common annotations are in the javax.common
or javax.common.security
packages. For example:import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.interceptor.ExcludeDefaultInterceptors;
See Specifying the Business and Other Interfaces.
See Specifying the Bean Type (Stateless, Stateful, Message-Driven).
See Injecting Resource Dependency into a Variable or Setter Method.
EntityManager
object and use the entity annotations to inject entity information.See Specifying Interceptors for Business Methods or Lifecycle Callback Events.
See Programming Application Exceptions for EJB 3.0 specific information.
See Securing Access to the EJB.
When using the EJB 3.0 programming model to program a bean, you are required to specify a business interface.
There are two ways you can specify the business interface for the EJB bean class:
Typically, if an EJB bean class implements an interface, it is assumed to be the business interface of the EJB. Additionally, the business interface is assumed to be the local interface unless you explicitly denote it as the remote interface, either by using the javax.ejb.Remote
annotation or updating the appropriate EJB deployment descriptor. You can specify the javax.ejb.Remote
annotation. as well as the javax.ejb.Local
annotation, in either the business interface itself, or the bean class that implements the interface.
A bean class can have more than one interface. In this case (excluding the interfaces listed below), you must specify the business interface of the EJB by explicitly using the javax.ejb.Local
or javax.ejb.Remote
annotations in either the business interface itself, the bean class that implements the business interface, or the appropriate deployment descriptor.
The following interfaces are excluded when determining whether the bean class has more than one interface:
The following code snippet shows how to specify the business interface of a bean class by explicitly implementing the interface:
public class ServiceBean
implements Service
For the full example, see Example of a Simple Stateless EJB
There is only one required metadata annotation in a 3.0 bean class: an annotation that specifies the type of bean you are programing. You must specify one, and only one, of the following:
@javax.ejb.Stateless
—Specifies that you are programming a stateless session bean.@javax.ejb.Stateful
—Specifies that you are programming a stateful session bean.@javax.ejb.MessageDriven
—Specifies that you are programming a message-driven bean.@javax.ejb.Entity
—Specifies that you are programming an entity bean.Note: | Programming a 3.0 entity is discussed in a separate document. See Enterprise JavaBeans 3 Persistence in the BEA Kodo documentation. |
Although not required, you can specify attributes of the annotations to further describe the bean type. For example, you can set the following attributes for all bean types:
If you are programming a message-driven bean, then you can specify the following optional attributes:
The following code snippet shows how to specify that a bean is a stateless session bean:
@Stateless
public class ServiceBean
implements Service
For the full example, see Example of a Simple Stateless EJB.
Dependency injection is when the EJB container automatically supplies (or injects) a bean’s variable or setter method with a reference to a resource or another environment entry in the bean’s context. Dependency injection is simply an easier-to-program alternative to using the javax.ejb.EJBContext
interface or JNDI APIs to look up resources.
You specify dependency injection by annotating a variable or setter method with one of the following annotations, depending on the type of resource you want to inject:
@javax.ejb.EJB
—Specifies a dependency on another EJB.@javax.annotation.Resource
—Specifies a dependency on an external resource, such as a JDBC datasource or a JMS destination or connection factory. Note: | This annotation is not specific to EJB; rather, it is part of the common set of metadata annotations used by many different types of Java EE components. |
Both annotations have an equivalent grouping annotation to specify a dependency on multiple resources (@javax.ejb.EJBs
and @javax.annotation.Resources
).
Although not required, you can specify attributes to these dependency annotations to explicitly describe the dependent resource. The amount of information you need to specify depends upon its usage context and how much information the EJB container can infer from that context. See javax.ejb.EJB and javax.annotation.Resource for detailed information on the attributes and when you should specify them.
The following code snippet shows how to use the @javax.ejb.EJB
annotation to inject a dependency on an EJB into a variable; only the relevant parts of the bean file are shown:
package examples;
import javax.ejb.EJB;
...
@Stateful
public class AccountBean
implements Account
{
@EJB(beanName="ServiceBean")
private Service service;
...
public void sayHelloFromAccountBean() {
service.sayHelloFromServiceBean();
}
In the preceding example, the private variable service
is annotated with the @javax.ejb.EJB
annotation, which makes reference to the EJB with a bean name of ServiceBean
. The data type of the service variable is Service
, which is the business interface implemented by the ServiceBean
bean class. As soon as the EJB container creates the AccountBean
EJB, the container injects a reference to ServiceBean
into the service
variable; the variable then has direct access to all the business methods of SessionBean
, as shown in the sayHelloFromAccountBean
method implementation in which the sayHelloFromServiceBean
method is invoked.
This section describes how to invoke and update a 3.0 entity from within a session bean.
Note: | It is assumed in this section that you have already programmed the entity, as well as configured the database resources that support the entity. For details on that topic, see Enterprise JavaBeans 3 Persistence in the BEA Kodo documentation. |
An entity is a persistent object that represents datastore records; typically an instance of an entity represents a single row of a database table. Entities make it easy to query and update information in a persistent store from within another Java EE component, such as a session bean. A Person
entity, for example, might include name
, address
, and age fields
, each of which correspond to the columns of a table in a database. Using an javax.persistence.EntityManager
object to access and manage the entities, you can easily retrieve a Person
record, based on either their unique id or by using a SQL query, and then change the information and automatically commit the information to the underlying datastore.
The following sections describe the typical programming tasks you perform in your session bean to interact with entities:
In your session bean, use the following metadata annotations inject entity information into a variable:
@javax.persistence.PersistenceContext
—Injects a persistence context into a variable of data type javax.persistence.EntityManager
. A persistence context is simply a set of entities such that, for any persistent identity, there is a unique entity instance. The persistence.xml
file defines and names the persistence contexts available to a session bean.@javax.persistence.PersistenceContext
s—Specifies a set of multiple persistence contexts.@javax.persistence.PersistenceUnit
—Injects a persistence context into a variable of data type javax.persistence.EntityManagerFactory
. @javax.persistence.PersistenceUnits
—Specifies a set of multiple persistence contexts.
The @PersistenceContext
and @PersistenceUnit
annotations perform a similar function: inject persistence context information into a variable; the main difference is the data type of the instance into which you inject the information. If you prefer to have full control over the lifecycle of the EntityManager
in your session bean, then use @PersistenceUnit
to inject into an EntityManagerFactory
instance, and then write the code to manually create an EntityManager
and later destroy when you are done, to release resources. If you prefer that the EJB container manage the lifecycle of the EntityManager
, then use the @PersistenceContext
annotation to inject directly into an EntityManager
.
The following example shows how to inject a persistence context into the variable em
of data type EntityManager
; relevant code is shown in bold:
package examples;
import javax.ejb.Stateless;
import javax.persistence.PersistenceContext;
import javax.persistence.EntityManager;
@Stateless
public class ServiceBean
implements Service
{
@PersistenceContext private EntityManager em;
...
Once you have instantiated an EntityManager
object, you can use its methods to interact with the entities in the persistence context. This section discusses the methods used to identify and manage the lifecycle of an entity; see
EntityManager in the
BEA Kodo documentation for additional uses of the EntityManager
, such as transaction management, caching, and so on.
Note: | For clarity, this section assumes that the entities are configured such that they represent actual rows in a database table. |
Use the EntityManager.find()
method to find a row in a table based on its primary key. The find
method takes two parameters: the entity class that you are querying, such as Person.class
, and the primary key value for the particular row you want to retrieve. Once you retrieve the row, you can use standard getXXX
methods to get particular properties of the entity. The following code snippet shows how to retrieve a Person
with whose primary key value is 10
, and then get their address:
public List<Person> findPerson () {
Person p = em.find(Person.class, 10);
Address a = p.getAddress();
Query q = em.createQuery("select p from Person p where p.name = :name");
q.setParameter("name", "Patrick");
List<Person> l = (List<Person>) q.getResultList();
return l;
}
The preceding example also shows how to use the EntityManager.createQuery()
method to create a Query
object that contains a custom SQL query; by contrast, the EntityManager.find()
method allows you to query using only the table’s primary key. In the example, the table is queried for all Person
s whose first name is Patrick
; the resulting set of rows populates the List<Person>
object and is returned to the findPerson()
invoker.
To create a new entity instance (and thus add a new row to the database), use the EntityManager.persist
method, as shown in the following code snippet
@TransactionAttribute(REQUIRED)
public Person createNewPerson(String name, int age) {
Person p = new Person(name, age);
em.persist(p); // register the new object with the database
Address a = new Address();
p.setAddress(a);
em.persist(a); // depending on how things are configured, this may or may not be required
return p;
}
Note: | Whenever you create or update an entity, you must be in a transaction, which is why the @TransactionAttribute annotation in the preceding example is set to REQUIRED . |
The preceding example shows how to create a new Person, based on parameters passed to the createNewPerson
method, and then call the EntityManager.persist method to automatically add the row to the database table.
The preceding example also shows how to update the newly-created Person
entity (and thus new table row) with an Address
by using the setAddress()
entity method. Depending on the cascade configuration of the Person
entity, the second persist()
call may not be necessary; this is because the call to the setAddress()
method might have automatically triggered an update to the database. For more information about cascading operations, see
Cascade Type in the
BEA Kodo documentation.
If you use the EntityManager.find()
method to find an entity instance, and then use a setXXX
method to change a property of the entity, the database is automatically updated and you do not need to explicitly call the EntityManager.persist()
method, as shown in the following code snippet:
@TransactionAttribute(REQUIRED)
public Person changePerson(int id, int newAge) {
Person p = em.find(Person.class, id);
p.setAge(newAge);
return p;
}
In the preceding example, the call to the Person.setAge()
method automatically triggered an update to the appropriate row in the database table.
Finally, you can use the EntityManager.merge()
method to quickly and easily update a row in the database table based on an update to an entity made by a client, as shown in the following example:
@TransactionAttribute(REQUIRED)
public Person applyOfflineChanges(Person pDTO) {
return em.merge(pDTO);
}
In the example, the applyOfflineChanges()
method is a business method of the session bean that takes as a parameter a Person
, which has been previously created by the session bean client. When you pass this Person
to the EntityManager.merge()
method, the EJB container automatically finds the existing row in the database table and automatically updates the row with the new data. The merge()
method then returns a copy of this updated row.
An interceptor is a method that intercepts a business method invocation or a lifecycle callback event. There are two types of interceptors: those that intercept business methods and those that intercept lifecycle callback methods.
Interceptors can be specified for session and message-driven beans.
You can program an interceptor method inside the bean class itself, or in a separate interceptor class which you then associate with the bean class with the @javax.interceptor.Interceptors
annotation. You can create multiple interceptor methods that execute as a chain in a particular order.
Interceptor instances may hold state. The lifecycle of an interceptor instance is the same as that of the bean instance with which it is associated. Interceptors can invoke JNDI, JDBC, JMS, other enterprise beans, and the EntityManager. Interceptor methods share the JNDI name space of the bean for which they are invoked. Programming restrictions that apply to enterprise bean components to apply to interceptors as well.
Interceptors are configured using metadata annotations in the javax.interceptor
package, as described in later sections.
The following topics discuss how to actually program interceptors for your bean class:
The following procedure provides the typical steps to specify and program interceptors for your bean class.
See Example of a Simple Stateful EJB for an example of specifying interceptors and Example of an Interceptor Class for an example of programming an interceptor class.
@javax.interceptor.Interceptors
annotation to associate the interceptor class with the bean class. The method in the interceptor class annotated with the @javax.interceptor.AroundInvoke
annotation then becomes a business method interceptor method of the bean class. Similarly, the methods annotated with the lifecycle callback annotations become the lifecycle callback interceptor methods of the bean class.You can specify any number of interceptor classes for a given bean class—the order in which they execute is the order in which they are listed in the annotation. If you specify the interceptor class at the class-level, the interceptor methods apply to all appropriate bean class methods. If you specify the interceptor class at the method-level, the interceptor methods apply to only the annotated method.
@javax.interceptor.ExcludeClassInterceptors
annotation to exclude any interceptors defined at the class-level.@javax.interceptor.ExcludeDefaultInterceptors
annotation to exclude any default interceptors that you might define later. Default interceptors are configured in the ejb-jar.xml
deployment descriptor, and apply to all EJBs in the JAR file, unless you explicitly use the annotation to exclude them.The interceptor class is a plain Java class that includes the interceptor annotations to specify which methods intercept business methods and which intercept lifecycle callback methods.
Interceptor classes support dependency injection, which is performed when the interceptor class instance is created, using the naming context of the associated enterprise bean.
You must include a public no-argument constructor.
You can have any number of methods in the interceptor class, but restrictions apply as to how many methods can be annotated with the interceptor annotations, as described in the following sections.
For an example, see Example of an Interceptor Class.
You specify business method interceptor methods by annotating them with the @AroundInvoke
annotation.
An interceptor class or bean class can have only one method annotated with @AroundInvoke
. To specify that multiple interceptor methods execute for a given business method, you must associate multiple interceptor classes with the bean file, in addition to optionally specifying an interceptor method in the bean file itself. The order in which the interceptor methods execute is the order in which the associated interceptor classes are listed in the @Interceptor
annotation. Interceptor methods in the bean class itself execute after those defined in the interceptor classes.
You cannot annotate a business method itself with the @AroundInvoke
annotation.
The signature of an @AroundInvoke
method must be:
Object <METHOD>(InvocationContext) throws Exception
The method annotated with the @AroundInvoke
annotation must always call InvocationContext.proceed()
or neither the business method will be invoked nor any subsequent @AroundInvoke
methods. See Saving State Across Interceptors With the InvocationContext API for additional information about the InvocationContext
API.
Business method interceptor method invocations occur within the same transaction and security context as the business method for which they are invoked. Business method interceptor methods may throw runtime exceptions or application exceptions that are allowed in the throws
clause of the business method.
For an example, see Example of an Interceptor Class.
You specify a method to be a lifecycle callback interceptor method so that it can receive notification of life cycle events from the EJB container. Life cycle events include creation, passivation, and destruction of the bean instance.
You can name the lifecycle callback interceptor method anything you want; this is different from the EJB 2.X programming model in which you had to name the methods ejbCreate()
, ejbPassivate()
, and so on.
You use the following lifecycle interceptor annotations to specify that a method is a lifecycle callback interceptor method:
@javax.ejb.PrePassivate
—Specifies the method that the EJB container notifies when it is about to passivate a stateful session bean.@javax.ejb.PostActivate
—Specifies the method that the EJB container notifies right after it has reactivated a stateful session bean.@javax.annotation.PostConstruct
—Specifies the method that the EJB container notifies before it invokes the first business method and after it has done dependency injection. You typically apply this annotation to the method that performs initialization. Note: | This annotation is in the javax.annotation package, rather than javax.ejb . |
@javax.annotation.PreDestroy
—Specifies the method that the EJB container notifies right before it destroys the bean instance. You typically apply this annotation to the method that release resources that the bean class has been holding. Note: | This annotation is in the javax.annotation package, rather than javax.ejb . |
You use the preceding annotations the same way, whether the annotated method is in the bean class or in a separate interceptor class. You can annotate the same method with more than one annotation.
You can also specify any subset or combination of lifecycle callback annotations in the bean class or in an associated interceptor class. However, the same callback annotation may not be specified more than once in a given class. If you do specify a callback annotation more than once in a given class, the EJB will not deploy.
To specify that multiple interceptor methods execute for a given lifecycle callback event, you must associate multiple interceptor classes with the bean file, in addition to optionally specifying the lifecycle callback interceptor method in the bean file itself. The order in which the interceptor methods execute is the order in which the associated classes are listed in the @Interceptor
annotation. Interceptor methods in the bean class itself execute after those defined in the interceptor classes.
The signature of the annotated methods depends on where the method is defined:
See Saving State Across Interceptors With the InvocationContext API for additional information about the InvocationContext
API.
See javax.ejb.PostActivate, javax.ejb.PrePassivate, javax.annotation.PostConstruct, and javax.annotation.PreDestroy for additional requirements when programming the lifecycle interceptor class.
For an example, see Example of an Interceptor Class.
Default interceptor methods apply to all components in a particular EJB JAR file or exploded directory, and thus can only be configured in the ejb-jar.xml
deployment descriptor file and not with metadata annotations, which apply to a particular EJB.
The EJB container invokes default interceptor methods, if any, before all other interceptors defined for an EJB (both business and lifecycle). If you do not want the EJB container to invoke the default interceptors for a particular EJB, specify the class-level @javax.interceptor.ExcludeDefaultInterceptors
annotation in the bean file.
In the ejb-jar.xml
file, use the <interceptor-binding>
child element of <assembly-descriptor>
to specify default interceptors. In particular, set the <ejb-name>
child element to *
, which means the class applies to all EJBs, and then the <interceptor-class>
child element to the name of the interceptor class.
The following snippet from an ejb-jar.xml
file shows how to specify the default interceptor class org.mycompany.DefaultIC
:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
...
<assembly-descriptor>
...
<interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>org.mycompany.DefaultIC</interceptor-class>
</interceptors>
</assembly-descriptor>
</ejb-jar>
Use the javax.interceptor.InvocationContext
API to pass state information between the interceptors that execute for a given business method or lifecycle callback. The EJB Container passes the same InvocationContext
instance to each interceptor method, so you can, for example save information when the first business method interceptor method executes, and then retrieve this information for all subsequent interceptor methods that execute for this business method. The InvocationContext
instance is not shared between business method or lifecycle callback invocations.
All interceptor methods must have an InvocationContext
parameter. You can then use the methods of the InvocationContext
interface to get and set context information. The InvocationContext
interface is shown below:
public interface InvocationContext {
public Object getBean();
public Method getMethod();
public Object[] getParameters();
public void setParameters(Object[]);
public java.util.Map getContextData();
public Object proceed() throws Exception;
}
The getBean
method returns the bean instance. The getMethod
method returns the name of the business method for which the interceptor method was invoked; in the case of lifecycle callback interceptor methods, getMethod
returns null.
The proceed
method causes the invocation of the next interceptor method in the chain, or the business method itself if called from the last @AroundInvoke
interceptor method.
For an example of using InvocationContext
, see Example of an Interceptor Class.
If you specified in the business interface that a method throws an application method, then you must program the exception as a separate class from the bean class.
Use the @javax.ejb.ApplicationException
annotation to specify that an exception class is an application exception thrown by a business method of the EJB. The EJB container reports the exception directly to the client in the event of the application error.
Use the rollback
Boolean attribute of the @ApplicationException
annotation to specify whether the application error causes the current transaction to be rolled back. By default, the current transaction is not rolled back in event of the error.
You can annotate both checked and unchecked exceptions with this annotation.
The following ProcessingException.java
file shows how to use the @ApplicationException
annotation to specify that an exception class is an application exception thrown by one of the business methods of the EJB:
package examples;
import javax.ejb.ApplicationException;
/**
* Application exception class thrown when there was a processing error
* with a business method of the EJB. Annotated with the
* @ApplicationException annotation.
*/
@ApplicationException()
public class ProcessingException extends Exception {
/**
* Catches exceptions without a specified string
*
*/
public ProcessingException() {}
/**
* Constructs the appropriate exception with the specified string
*
* @param message Exception message
*/
public ProcessingException(String message) {super(message);}
}
By default, any user can invoke the public methods of an EJB. If you want to restrict access to the EJB, you can use the following security-related annotations to specify the roles that are allowed to invoke all, or a subset, of the methods:
javax.annotation.security.DeclareRoles
—Explicitly lists the security roles that will be used to secure the EJB. javax.annotation.security.RolesAllowed
—Specifies the security roles that are allowed to invoke all the methods of the EJB (when specified at the class-level) or a particular method (when specified at the method-level.)javax.annotation.security.DenyAll
—Specifies that the annotated method can not be invoked by any role.javax.annotation.security.PermitAll
—Specifies that the annotated method can be invoked by all roles.javax.annotation.security.RunAs
—Specifies the role which runs the EJB. By default, the EJB runs as the user who actually invokes it.The preceding annotations can be used with many Java EE components that allow metadata annotations, not just EJB 3.0.
You create security roles and map users to roles using the WebLogic Server Administration Console to update your security realm. For details, see Manage Security Roles.
The following example shows a simple stateless session EJB that uses all of the security-related annotations; the code in bold is discussed after the example:
package examples;
import javax.ejb.Stateless;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.PermitAll;
import javax.annotation.security.DenyAll;
import javax.annotation.security.RolesAllowed;
import javax.annotation.security.RunAs;
/**
* Bean file that implements the Service business interface.
*/
@Stateless@DeclareRoles( { "admin", "hr" } )
@RunAs ("admin")
public class ServiceBean
implements Service
{
@RolesAllowed ( {"admin", "hr"} )
public void sayHelloRestricted() {
System.out.println("Only some roles can invoke this method.");
}
@DenyAll
public void sayHelloSecret() {
System.out.println("No one can invoke this method.");
}
@PermitAll
public void sayHelloPublic() {
System.out.println("Everyone can invoke this method.");
}
}
The main points to note about the preceding example are:
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.PermitAll;
import javax.annotation.security.DenyAll;
import javax.annotation.security.RolesAllowed;
import javax.annotation.security.RunAs;
@DeclareRoles
annotation explicitly specifies that the admin
and hr
security roles will later be used to secure some or all of the methods. This annotation is not required; any security role referenced in, for example, the @RolesReferenced
annotation is implicitly declared. However, explicitly declaring the security roles makes your code easier to read and understand.@RunAs
annotation specifies that, regardless of the user who actually invokes a particular method of the EJB, the EJB container runs the method as the admin
role, assuming, of course, that the original user is allowed to invoke the method.@RolesAllowed
annotation on the sayHelloRestricted
method specifies that only users mapped to the admin
and hr
roles are allowed to invoke the method.@DenyAll
annotation on the sayHelloSecret
method specifies that no one is allowed to invoke the method.@PermitAll
annotation on the sayHelloPublic
method specifies that all users mapped to any roles are allowed to invoke the method.By default, the EJB container invokes a business method within a transaction context. Additionally, the EJB container itself decides whether to commit or rollback a transaction; this is called container-managed transaction demarcation.
You can change this default behavior by using the following annotations in your bean file:
javax.ejb.TransactionManagement
—Specifies whether the EJB container or the bean file manages the demarcation of transactions. If you specify that the bean file manages it, then you must program transaction management in your bean file, typically using the Java Transaction API (JTA).javax.ejb.TransactionAttribute
—Specifies whether the EJB container invokes methods within a transaction.
For an example of using the javax.ejb.TransactionAttribute
annotation, see Example of a Simple Stateful EJB.
EJB 3.0 Metadata Annotations Reference, provides full reference information about the EJB 3.0 metadata annotations in alphabetical order. The tables in this section group the annotations based on what task they perform.
The following metadata annotations are not specific to EJB 3.0, but rather, are general security-related annotations in the javax.annotation.security
package.