EJB (Enterprise JavaBeans) is a standard architecture of an environment for hosting server tiers of enterprise component applications. The EJB standard has evolved through several major revisions, which, besides introducing particular features, have also included changing the programming interface due to the introduction of language annotations. The text in this section deals mostly with the latest version.
An EJB application consists of components called enterprise beans that reside in a container. The beans implement the business logic of the application, the container provides the beans with standard services including lifecycle, dependency management, persistency, transactions, and makes the beans accessible to the clients.
Beans come in three distinct types, namely session objects, entity objects and message driven objects. The session objects are further split into stateless, stateful and singleton variants. Each type is tailored to fill a specific role in a component application.
The dependency management can use the CDI (Contexts and Dependency Injection) framework. The framework defines scopes that associate beans with particular execution context. An execution context is responsible for obtaining contextual instances of beans, this typically involves creating instances and looking up created instances.
Containers. Environment providing services to enterprise application objects
Lifecycle management (creating and deleting instances)
Dependency management (resource and dependency injection)
Persistence and transactions
...
Enterprise Beans. Enterprise application objects managed by container
an object that lives within user session scope, state survives method invocation
an object that lives within user session scope, state only within method invocation
a singleton application object
an object representing persistent database state
an object that handles messages, state only within message handling
Scopes and Contexts.
public interface Context { public Class <? extends Annotation> getScope (); public <T> T get (Contextual <T> bean); public <T> T get (Contextual <T> bean, CreationalContext <T> creationalContext); ... }
instance bound to single injection point
context associated with single method invocation or request handling
context associated with an HTTP session
context associated with application execution
context associated with explicitly delimited UI interaction
@Stateful public class ASessionBean implements ABusinessInterface { // Injected reference to standard session context object @Resource public SessionContext sessionContext; // Method that is called after construction or activation @PostConstruct @PostActivate public void myInitMethod () { ... } // Method that is called before passivation or destruction @PreDestroy @PrePassivate public void myDoneMethod () { ... } // Some business methods ... public void myMethodOne (int iArgument) { ... } public int myMethodTwo (Object oArgument) { ... } // Business method with asynchronous interface @Asynchronous public Future<String> myAsynchronousMethod (String sArgument) { ... } // Business method that removes the bean instance @Remove public void myRemovalMethod () { ... } // Interceptor method that can also be in separate interceptor class @AroundInvoke public Object myInterceptor (InvocationContext inv) throws Exception { ... Object result = inv.proceed (); ... return (result); } }
method invocations serialized by the container
asynchronous method invocations handled by the container
business interface can be accessed both locally and remotely
references obtained through dependency injection or JNDI lookup
Client life cycle view.
accessible when reference first obtained
removed through explicit removal method
Container life cycle view.
instance may be passivated and activated
@Startup @Singleton public class ASingletonBean { // Injected reference to JNDI resource @Resource (lookup = "java:comp/env/jdbc/SomeDataSource") DataSource dataSource; // Method that is called after construction @PostConstruct public void myInitMethod () { ... } // Method that is called before destruction @PreDestroy public void myDoneMethod () { ... } // Some business methods ... public synchronized void myMethodOne (int iArgument) { ... } public synchronized int myMethodTwo (Object oArgument) { ... } }
concurrent method invocations possible
Container life cycle view.
construction timing determined by container
eager construction can be requested through annotation
Unless explicitly disabled, each EJB session bean instance is bound to some CDI context. The default scope is @Dependent
, which ties the EJB session bean instance lifecycle to the lifecycle of the injection point. An EJB session bean is therefore not necessarily associated with CDI session scope.
@MessageDriven (activationConfig = { @ActivationConfigProperty ( propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty ( propertyName = "destinationLookup", propertyValue = "jms/SomeQueue") }) public class AMessageBean implements MessageListener { public AMessageBean () { ... } @Override public void onMessage (Message aMessage) { ... } ... }
method invocations serialized by the container
multiple instances can be created by the container
message delivery order between instances is not defined
@Entity public class AnEntity { // With field based access fields are persistent by default private int someField; private String someOtherField; // Relationships among entities must be annotated @OneToMany private Collection <AnotherEntity> relatedEntities; // Every entity must have a primary key @Id private long aKeyField; // Field that is not persistent @Transient private String aTransientString; // Version field for optimistic concurrency @Version private long version = 0L; // Obligatory constructor with no arguments public AnEntity () { ... } // Additional business methods ... public void myMethodOne (int iArgument) { ... } public int myMethodTwo (Object oArgument) { ... } }
@Entity public class AnEntity { // With property based access fields are not persistent themselves private int someTransientField; private String someOtherTransientField; // Relationships among entities must be annotated private Collection <AnotherEntity> relatedEntities; @OneToMany public Collection <AnotherEntity> getRelatedEntities () { return (relatedEntities); } public void setRelatedEntities (Collection <AnotherEntity> entityCollection) { relatedEntities = entityCollection; } // Getter and setter methods for primary key private long aKeyField; @Id Long getAKeyField () { return (aKeyField); } public void setAKeyField (Long aKeyField) { this.aKeyField = aKeyField; } // Obligatory constructor with no arguments public AnEntity () { ... } // Additional business methods ... public void myMethodOne (int iArgument) { ... } public int myMethodTwo (Object oArgument) { ... } }
public interface EntityManager { void persist (Object entity); void refresh (Object entity); void remove (Object entity); void detach (Object entity); <T> T merge (T entity); void lock (Object entity, LockModeType lockMode); // Find by primary key <T> T find (Class <T> entityClass, Object primaryKey); // Find by primary key and return lazy reference <T> T getReference (Class <T> entityClass, Object primaryKey); // Clear persistence context and detach all entities void clear (); // Check whether persistence context contains managed entity boolean contains (Object entity); // Synchronize persistence context with database // Flush mode governs automatic synchronization // upon query execution or upon commit void flush (); FlushModeType getFlushMode (); void setFlushMode (FlushModeType flushMode); Query createQuery (String ejbqlString); Query createNamedQuery (String name); Query createNativeQuery (String sqlString); ... }
public interface Query { // Execute a query that returns a result list List getResultList (); // Execute a query that returns a single result Object getSingleResult(); // Execute an update query int executeUpdate (); // Methods used to fetch results step by step Query setMaxResults (int maxResult); Query setFirstResult (int startPosition); // Bind a parameter in a query Query setParameter (String name, Object value); Query setParameter (String name, Date value, TemporalType temporalType); Query setParameter (String name, Calendar value, TemporalType temporalType); Query setParameter (int position, Object value); Query setParameter (int position, Date value, TemporalType temporalType); Query setParameter (int position, Calendar value, TemporalType temporalType); }
The flat transaction model is supported. Transactions are demarcated either by the beans or by the container. When bean managed transaction demarcation is used, the individual methods of a bean can explicitly begin and commit or rollback a transaction. When container managed transaction demarcation is used, the individual methods of a bean can use transaction attributes, specified either in the method annotations or in the deployment descriptor. The transaction attributes tell the container how to demarcate the transactions.
@Stateful @TransactionManagement (BEAN) public class SomeBeanClass implements SomeBeanInterface { @Resource javax.Transaction.UserTransaction transaction; public void myMethodOne () { transaction.begin (); ... } public void myMethodTwo () { ... transaction.commit (); } } @Stateless public class SomeBeanClass implements SomeBeanInterface { @TransactionAttribute (REQUIRED) public void myMethod () { ... } }
bean demarcated transactions
transaction must not be active or exception is thrown
transaction must be active or exception is thrown
no specific demarcation performed by the container
active transaction suspended during call
active transaction used or new transaction started during call
active transaction suspended and new transaction started during call
The state of a session bean is not a transactional resource and therefore is not influenced by transaction commit or rollback. A session bean can implement the SessionSynchronization
interface to receive the afterBegin
, beforeCompletion
, afterCompletion
notifications. These can be used to commit or rollback the state of the bean explicitly.
JSR 345: Enterprise JavaBeans 3.2. http://jcp.org/en/jsr/detail?id=345
JSR 346: Contexts and Dependency Injection for Java EE 1.2. http://jcp.org/en/jsr/detail?id=346
JSR 338: Java Persistence 2.2. http://jcp.org/en/jsr/detail?id=338