5 Programming the Annotated EJB Class

This chapter describes how to program the annotated EJB 3.2 class file.

This chapter includes the following sections:

Overview of Metadata Annotations and EJB Bean Files

The WebLogic Server EJB 3.2 programming model uses the Java EE 7 metadata annotations feature in which you create an annotated EJB 3.2 bean file, compile the class with the standard Java compiler, and the resulting class can then be packaged into a target module for deployment. At runtime, WebLogic Server parses the annotations and applies the required behavioral aspects to the bean file.

Tip:

To reduce deployment time, you can also use the WebLogic compile tool weblogic.appc (or its Ant equivalent wlappc) to pre-compile a deployable archive file, (WAR, JAR, or EAR). Precompiling with weblogic.appc generates certain helper classes and performs validation checks to ensure your application is compliant.

The annotated 3.2 bean file is the core of your EJB. It contains the Java code that determines how your EJB behaves. The 3.2 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 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 following specifications:

See EJB 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.2, described in Iterative Development of Enterprise JavaBeans.

For more information on general EJB design and architecture, see the following documents:

Programming the Bean File: Requirements and Changes From EJB 2.x

The requirements for programming the EJB 3.2 bean class file are essentially the same as the EJB 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 EJB 2.x and EJB 3.2.

See Developing Enterprise JavaBeans, Version 2.1, for Oracle WebLogic Server for detailed information about the mandatory and optional requirements for programming the bean class.

Bean Class Requirements and Changes From EJB 2.x

The following bullets list the EJB 3.2 requirements for programming a bean class, as well as the EJB 2.x requirements that no longer apply:

  • The class must specify its bean type, typically using one of the following metadata annotations, although you can also override this using a deployment descriptor:

    • @javax.ejb.Stateless

    • @javax.ejb.Stateful

    • @javax.ejb.Singleton

    • @javax.ejb.MessageDriven

      Note:

      Oracle Kodo JPA/JDO is not supported in this release of WebLogic Server. However, if you still using Oracle Kodo, programming a 3.0 entity bean (@javax.ejb.Entity) is discussed in a separate document.

      Customers are encouraged to use Oracle TopLink, which supports JPA 2.1. Kodo supports only JPA 1.0. For more information, see Using Oracle TopLink in Oracle WebLogic Server.

  • If the bean is a session bean, the bean class can implement either:

    • The no-interface local client view type, which simplifies EJB development by providing local session bean access without requiring a separate local business interface. (As of EJB 3.2, MDBs can also use the no-interface local client view.)

    • The bean's business interface(s) or the methods of the bean's business interface(s), if any.

  • Session beans no longer need to implement javax.ejb.SessionBean, which means the bean no longer needs to implement the ejbXXX() methods, such as ejbCreate(), ejbPassivate(), and so on.

  • Stateful session beans no longer need to implement java.io.Serializable.

  • Message-driven beans no longer need to implement javax.ejb.MessageDrivenBean.

The following requirements are the same as in EJB 2.x and are provided only as a brief overview:

  • The class must be defined as public, must not be final, and must not be abstract. The class must be a top level class.

  • The class must have a public constructor that takes no parameters.

  • The class must not define the finalize() method.

  • If the bean is message-driven, the bean class must implement, directly or indirectly, the message listener interface required by the messaging type that it supports or the methods of the message listener interface. In the case of JMS, this is the javax.jms.MessageListener interface.

Bean Class Method Requirements

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:

  • The method names can be arbitrary.

  • The business method must be declared as public and must not be final or static.

  • The argument and return value types for a method must be legal types for RMI/IIOP if the method corresponds to a business method on the session bean's remote business interface or remote interface.

  • The throws clause may define arbitrary application exceptions.

The requirements for programming the message-driven bean class' methods are as follows:

  • The methods must implement the listener methods of the message listener interface.

  • The methods must be declared as public and must not be final or static.

Programming the Bean File

The sections that follow provide the recommended steps when programming the annotated EJB 3.2 class file.

Typical Steps When Programming the Bean File

The following procedure describes the typical basic steps when programming the 3.2 bean file for a EJB. The steps you follow depends, of course, on what your EJB does.

Refer to Simple Enterprise JavaBeans Examples, for code examples of the topics discussed in the remaining sections.

  1. Import the EJB 3.2 and other common annotations that will be used in your bean file. The general EJB annotations are in the javax.ejb package, the interceptor annotations are in the javax.interceptor package, the annotations to invoke a 3.2 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;
    
  2. Specify the interface that your EJB is going to implement, either a business interface or a no-interface view, as well as other standard interfaces. You can either explicitly implement the interface, or use an annotation to specify it.
  3. Use the required annotation to specify the type of bean you are programming (session or message-driven).
  4. Optionally, use dependency injection to use external resources, such as another EJB or other Java EE 7 object.
  5. Optionally, create an EntityManager object and use the entity annotations to inject entity information.
  6. Optionally, program and configure business method or life cycle callback method interceptor method. You can program the interceptor methods in the bean file itself, or in a separate Java file.
  7. If your business interface specifies that business methods throw application exceptions, you must program the exception class, the same as in EJB 2.x.

    See Programming Application Exceptions for EJB 3.2 specific information.

  8. Optionally, specify the security roles that are allowed to invoke the EJB methods using the security-related metadata annotations.
  9. Optionally, change the default transaction configuration in which the EJB runs.

Specifying the Business and Other Interfaces

The EJB 3.x local or remote client of a session bean written to the EJB 3.x API accesses a session bean through its business interface. A local client may also access a session bean through a no-interface view that exposes all public methods of the bean class.

Specifying the Business Interface

There are two ways you can specify the business interface for the EJB bean class:

  • By explicitly implementing the business interface, using the implements Java keyword.

  • By using metadata annotations (such as javax.ejb.Local and javax.ejb.Remote) to specify the business interface. In this case, the bean class does not need to explicitly implement the business interface.

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:

  • java.io.Serializable

  • java.io.Externalizable

  • Any of the interfaces defined by the javax.ejb package

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 Business Interface Stateless EJB.

Specifying the No-interface View

Client access to an enterprise bean that exposes a local, no-interface view is accomplished through either dependency injection or JNDI lookup. As of EJB 3.2, MDBs can also use the no-interface local client view.

  • To obtain a reference to the no-interface view of an enterprise bean through dependency injection, use the javax.ejb.EJB annotation and specify the enterprise bean's implementation class:

    @EJB
    ExampleBean exampleBean;
    
  • To obtain a reference to the no-interface view of an enterprise bean through JNDI lookup, use the javax.naming.InitialContext interface's lookup method:

    ExampleBean exampleBean = (ExampleBean)
    InitialContext.lookup("java:module/ExampleBean");
    

Clients do not use the new operator to obtain a new instance of an enterprise bean that uses a no-interface view.

There are code examples of using the No-interface client view bundled in the WebLogic Server distribution kit. See EJB 3.1: Example of Simplified No-interface Programming and Packaging in a WAR File and EJB 3.2: Example of a Message-Driven Bean with No-Methods Listener.

For more detailed information about the implementing the no-interface client view, see "Accessing Local Enterprise Beans Using the No-Interface View" in the "Enterprise Beans" chapter of the Java EE 7 Tutorial at http://docs.oracle.com/javaee/7/tutorial/index.html.

Specifying the Bean Type (Stateless, Singleton, Stateful, or Message-Driven)

There is only one required metadata annotation in a 3.2 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.Singleton—Specifies that you are programming a singleton 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.

    Note:

    Oracle Kodo JPA/JDO is not supported in this release of WebLogic Server. However, if you still using Oracle Kodo, programming a 3.0 entity bean (@javax.ejb.Entity) is discussed in a separate document.

    Customers are encouraged to use Oracle TopLink, which supports JPA 2.1. Kodo supports only JPA 1.0. For more information, see Using Oracle TopLink in Oracle WebLogic Server.

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:

  • name—Name of the bean class; the default value is the unqualified bean class name.

  • mappedName—Product-specific name of the bean.

  • description—Description of what the bean does.

If you are programming a message-driven bean, then you can specify the following optional attributes:

  • messageListenerInterface—Specifies the message listener interface, if you haven't explicitly implemented it or if the bean implements additional interfaces.

  • activationConfig—Specifies an array of activation configuration name-value pairs that configure the bean in its operational environment.

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 Business Interface Stateless EJB.

Injecting Resource Dependency into a Variable or Setter Method

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.

Invoking a 3.0 Entity

This section describes how to invoke and update a 3.0 entity from within a session bean.

Note:

Oracle TopLink, a JPA 2.1 persistence provider, is the default JPA provider, replacing Kodo, which was the default provider in previous releases. Any application that does not specify a JPA provider in persistence.xml will now use TopLink by default. For more information, see Configuring the Persistence Provider in Oracle WebLogic Server.

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:

Injecting Persistence Context Using Metadata Annotations

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.PersistenceContexts—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 life cycle 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 life cycle 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;

...
Finding an Entity Using the EntityManager API

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 life cycle of an entity; see Using Oracle TopLink in Oracle WebLogic Server. 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 Persons whose first name is Patrick; the resulting set of rows populates the List<Person> object and is returned to the findPerson() invoker.

Creating and Updating an Entity Using EntityManager

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 Using Oracle TopLink in Oracle WebLogic Server.

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.

Specifying Interceptors for Business Methods or Life Cycle Callback Events

An interceptor is a method that intercepts a business method invocation or a life cycle callback event. There are two types of interceptors: those that intercept business methods and those that intercept life cycle 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 life cycle 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:

Specifying Business or Life Cycle Interceptors: Typical Steps

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.

  1. Decide whether interceptor methods are programmed in bean class or in a separate interceptor class.

  2. If you decide to program the interceptor methods in a separate interceptor class

    1. Program the class, as described in Programming the Interceptor Class.

    2. In your bean class, use the @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 life cycle callback annotations become the life cycle 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.

  3. In the bean class or interceptor class (wherever you are programming the interceptor methods), program business method interceptor methods, as described in Programming Business Method Interceptor Methods.

  4. In the bean class or interceptor class (wherever you are programming the interceptor methods), program life cycle callback interceptor methods, as described in Programming Business Method Interceptor Methods.

  5. In the bean class, optionally annotate methods with the @javax.interceptor.ExcludeClassInterceptors annotation to exclude any interceptors defined at the class-level.

  6. In the bean class, optionally annotate the class or methods with the @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.

  7. Optionally specify default interceptors for the entire EJB JAR file, as described in Specifying Default Interceptor Methods.

Programming the Interceptor Class

The interceptor class is a plain Java class that includes the interceptor annotations to specify which methods intercept business methods and which intercept life cycle 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.

Programming Business Method Interceptor Methods

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.

Programming Asynchronous Business Methods

Session beans can implement asynchronous methods, business methods where control is returned to the client by the enterprise bean container before the method is invoked on the session bean instance. Clients may then use the Java SE concurrency API to retrieve the result, cancel the invocation, and check for exceptions. Asynchronous methods are typically used for long-running operations, for processor-intensive tasks, for background tasks, to increase application throughput, or to improve application response time if the method invocation result isn't required immediately.

When a session bean client invokes a typical non-asynchronous business method, control is not returned to the client until the method has completed. Clients calling asynchronous methods, however, immediately have control returned to them by the enterprise bean container. This allows the client to perform other tasks while the method invocation completes. If the method returns a result, the result is an implementation of the java.util.concurrent.Future<V> interface, where “V" is the result value type. The Future<V> interface defines methods the client may use to check if the computation is completed, wait for the invocation to complete, retrieve the final result, and cancel the invocation.

Asynchronous method invocation semantics only apply to the no-interface, local business, and remote business client views. Methods exposed through the EJB 2.x local, EJB 2.x remote, and Web service client views must not be designated as asynchronous.

For detailed instructions on creating an asynchronous business method, see "Asynchronous Method Invocation" in the "Enterprise Beans" chapter of the Java EE 7 Tutorial at http://docs.oracle.com/javaee/7/tutorial/index.html.

Programming Life Cycle Callback Interceptor Methods

You specify a method to be a life cycle 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 life cycle 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 life cycle interceptor annotations to specify that a method is a life cycle 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 life cycle 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 life cycle callback event, you must associate multiple interceptor classes with the bean file, in addition to optionally specifying the life cycle 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:

  • Life cycle callback methods defined on a bean class have the following signature:

     void <METHOD>()
    
  • Life cycle callback methods defined on an interceptor class have the following signature:

     void <METHOD>(InvocationContext)
    

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 life cycle interceptor class.

For an example, see Example of an Interceptor Class.

Specifying Default Interceptor Methods

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 life cycle). 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.2"
     xmlns="xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
           http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd">

...

   <assembly-descriptor>

...

      <interceptor-binding>
        <ejb-name>*</ejb-name>
        <interceptor-class>org.mycompany.DefaultIC</interceptor-class>
      </interceptor-binding>

   </assembly-descriptor>

</ejb-jar>
Saving State Across Interceptors With the InvocationContext API

Use the javax.interceptor.InvocationContext API to pass state information between the interceptors that execute for a given business method or life cycle 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 life cycle 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 life cycle 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.

Programming Application Exceptions

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);}
}

Securing Access to the EJB

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.2.

You create security roles and map users to roles using the WebLogic Server Administration Console to update your security realm. See Manage Security Roles in the Oracle WebLogic Server Administration Console Online Help.

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 the security-related metadata annotations:

    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;
    
  • The class-level @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.

  • The class-level @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.

  • The @RolesAllowed annotation on the sayHelloRestricted method specifies that only users mapped to the admin and hr roles are allowed to invoke the method.

  • The @DenyAll annotation on the sayHelloSecret method specifies that no one is allowed to invoke the method.

  • The @PermitAll annotation on the sayHelloPublic method specifies that all users mapped to any roles are allowed to invoke the method.

Specifying Transaction Management and Attributes

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.

Complete List of Metadata Annotations By Function

The tables in the sections that follow group the annotations based on what task they perform. EJB Metadata Annotations Reference, provides full reference information about the EJB 3.2 metadata annotations in alphabetical order.

Annotations to Specify the Bean Type

The following summarize the annotations used to specify the bean type.

Table 5-1 Annotations to Specify the Bean Type

Annotation Description
@javax.ejb.Stateless

Specifies that the bean class is a stateless session bean. For more information, see javax.ejb.Stateless.

@javax.ejb.Singleton

Specifies that the bean class is a singleton session bean. For more information, see javax.ejb.Singleton.

@javax.ejb.Stateful

Specifies that the bean class is a stateful session bean. For more information, see javax.ejb.Startup.

@javax.ejb.Init

Specifies the correspondence of a stateful session bean class method with a create<METHOD> method for an adapted EJB 2.1 EJBHome and/or EJBLocalHome client view. For more information, see javax.ejb.Init.

@javax.ejb.Remove

Specifies a remove method of a stateful session bean. For more information, see javax.ejb.Remove.

@javax.ejb.MessageDriven

Specifies that the bean class is a message-driven bean. For more information, see javax.ejb.MessageDriven.

@javax.ejb.ActivationConfigProperty

Specifies properties used to configure a message-driven bean in its operational environment. For more information, see javax.ejb.ActivationConfigProperty.

Annotations to Specify the Local or Remote Interfaces

The following summarize the annotations used to specify the local or remote interfaces.

Table 5-2 Annotations to Specify the Local or Remote Interfaces

Annotation Description
@javax.ejb.Local

Specifies a local interface of the bean. For more information, see javax.ejb.Local.

@javax.ejb.Remote

Specifies a remote interface of the bean. For more information, see javax.ejb.Remote.

Annotations to Support EJB 2.x Client View

The following summarize the annotations used to support EJB 2.x client view.

Table 5-3 Annotations to Support EJB 2.x Client View

Annotation Description
@javax.ejb.LocalHome

Specifies a local home interface of the bean. For more information, see javax.ejb.LocalHome.

@javax.ejb.RemoteHome

Specifies a remote home interface of the bean. For more information, see javax.ejb.RemoteHome.

Annotations to Invoke a 3.0 Entity Bean

The following summarize the annotations used to invoke a 3.0 entity bean.

Table 5-4 Annotations to Invoke a 3.0 Entity Bean

Annotation Description
@javax.persistence.PersistenceContext

Specifies a dependency on an EntityManager persistence context. For more information, see javax.persistence.PersistenceContext.

@javax.persistence.PersistenceContexts

Specifies one or more PersistenceContext annotations. For more information, see javax.persistence.PersistenceContexts.

@javax.persistence.PersistenceUnit

Specifies a dependency on an EntityManagerFactory. For more information, see javax.persistence.PersistenceUnit.

@javax.persistence.PersistenceUnits

Specifies one or more PersistenceUnit annotations. For more information, see javax.persistence.PersistenceUnits.

Transaction-Related Annotations

The following summarize the annotations used for transactions.

Table 5-5 Transaction-Related Annotations

Annotation Description
@javax.ejb.TransactionManagement

Specifies the transaction management demarcation type (container- or bean-managed). For more information, see javax.ejb.TransactionManagement.

@javax.ejb.TransactionAttribute

Specifies whether a business method is invoked within the context of a transaction. For more information, see javax.ejb.TransactionManagement.

Annotations to Specify Interceptors

The following summarize the annotations used to specify interceptors.

Table 5-6 Annotations to Specify Interceptors

Annotation Description
@javax.interceptor.Interceptors

Specifies the list of interceptor classes associated with a bean class or method. For more information, see javax.interceptor.Interceptors.

@javax.interceptor.AroundInvoke

Specifies an interceptor method. For more information, see javax.interceptor.AroundInvoke.

@javax.interceptor.ExcludeClassInterceptors

Specifies that, when the annotated method is invoked, the class-level interceptors should not invoke. For more information, see javax.interceptor.ExcludeClassInterceptors.

@javax.interceptor.ExcludeDefaultInterceptors

Specifies that, when the annotated method is invoked, the default interceptors should not invoke. For more information, see javax.interceptor.ExcludeDefaultInterceptors.

Annotations to Specify Life Cycle Callbacks

The following summarize the annotations used to specify life cycle callbacks.

Table 5-7 Annotations to Specify Life Cycle Callbacks

Annotation Description
@javax.ejb.PostActivate

Designates a method to receive a callback after a stateful session bean has been activated. For more information, see javax.ejb.PostActivate.

@javax.ejb.PrePassivate

Designates a method to receive a callback before a stateful session bean is passivated. For more information, see javax.ejb.PrePassivate.

@javax.annotation.PostConstruct

Specifies the method that needs to be executed after dependency injection is done to perform any initialization. For more information, see javax.annotation.PostConstruct.

@javax.annotation.PreDestroy

Specifies a method to be a callback notification to signal that the instance is in the process of being removed by the container. For more information, see javax.annotation.PreDestroy.

Security-Related Annotations

The following metadata annotations are not specific to EJB 3.2, but rather, are general security-related annotations in the javax.annotation.security package.

Table 5-8 Security-Related Annotations

Annotation Description
@javax.annotation.security.DeclareRoles

Specifies the references to security roles in the bean class. For more information, see javax.annotation.security.DeclareRoles.

@javax.annotation.security.RolesAllowed

Specifies the list of security roles that are allowed to invoke the bean's business methods. For more information, see javax.annotation.security.RolesAllowed.

@javax.annotation.security.PermitAll

Specifies that all security roles are allowed to invoke the method. For more information, see javax.annotation.security.PermitAll.

@javax.annotation.security.DenyAll

Specifies that no security roles are allowed to invoke the method. For more information, see javax.annotation.security.DenyAll.

@javax.annotation.security.RunAs

Specifies the security role which the method is run as. For more information, see javax.annotation.security.RunAs.

Context Dependency Annotations

The following summarize the annotations used for context dependency.

Table 5-9 Context Dependency Annotations

Annotation Description
@javax.ejb.EJB

Specifies a dependency to an EJB business interface or home interface. For more information, see javax.ejb.EJB.

@javax.ejb.EJBs

Specifies one or more @EJB annotations. For more information, see javax.ejb.EJBs.

@javax.annotation.Resource

Specifies a dependency on an external resource in the bean's environment. For more information, see javax.annotation.Resource.

@javax.annotation.Resources

Specifies one or more @Resource annotations. For more information, see javax.annotation.Resources.

Timeout and Exceptions Annotations

The following summarize the annotations used for timeout and exceptions.

Table 5-10 Timeout and Exception Annotations

Annotation Description
@javax.ejb.Timeout

Specifies the timeout method of the bean class. For more information, see javax.ejb.Timeout.

@javax.ejb.ApplicationException

Specifies that an exception is an application exception and should be reported to the client directly. For more information, see javax.ejb.ApplicationException.

Timer and Scheduling Annotations

The following summarize the annotations used for timers scheduling-specific annotations.

Table 5-11 Timer and Scheduling Annotations

Annotation Description
@javax.ejb.Timeout

Specifies the timeout method of the bean class. For more information, see javax.ejb.Timeout.

@javax.ejb.ApplicationException

Specifies that an exception is an application exception and should be reported to the client directly. For more information, see javax.ejb.ApplicationException.