Identify correct and incorrect statements or examples about how enterprise beans declare dependencies on external resources using JNDI or dependency injection, including the general rules for using JNDI, annotations and/or deployment descriptors, EJB references, connection factories, resource environment entries, and persistence context and persistence unit references.

Enterprise Bean's Environment as a JNDI Naming Context (declare dependencies on external resources)

The enterprise bean's environment is a mechanism that allows customization of the enterprise bean's business logic during deployment or assembly. The enterprise bean's environment allows the enterprise bean to be customized without the need to access or change the enterprise bean's source code.

Annotations and deployment descriptors are the main vehicles for conveying access information to the application assembler and deployer about beans' requirements for customization of business logic and access to external information.

The container implements the enterprise bean’s environment, and provides it as a JNDI naming context. The enterprise bean's environment is used as follows:

  1. The enterprise bean makes use of entries from the environment. Entries from the environment may be injected by the container into the bean's fields or methods, or the methods of the bean may access the environment using the EJBContext lookup method or the JNDI interfaces. The Bean Provider declares in Java language metadata annotations or in the deployment descriptor all the environment entries that the enterprise bean expects to be provided in its environment at runtime.

  2. The container provides an implementation of the JNDI naming context that stores the enterprise bean environment. The container also provides the tools that allow the Deployer to create and manage the environment of each enterprise bean.

  3. The Deployer uses the tools provided by the container to create and initialize the environment entries that are declared by means of the enterprise bean's annotations or deployment descriptor. The Deployer can set and modify the values of the environment entries.

  4. The container injects entries from the environment into the enterprise bean's fields or methods as specified by the bean's metadata annotations or the deployment descriptor.

  5. The container makes the environment naming context available to the enterprise bean instances at runtime. The enterprise bean's instances can use the EJBContext lookup method or the JNDI interfaces to obtain the values of the environment entries.

Sharing of Environment Entries

Each enterprise bean defines its own set of environment entries. All instances of an enterprise bean share the same environment entries; the environment entries are not shared with other enterprise beans. Enterprise bean instances are not allowed to modify the bean's environment at runtime.

In general, lookups of objects in the JNDI java: namespace are required to return a NEW INSTANCE of the requested object every time. Exceptions are allowed for the following:

In these cases, a shared instance of the object may be returned. In all other cases, a NEW INSTANCE of the requested object must be returned on each lookup. Note that, in the case of resource adapter connection objects, it is the resource adapter's ManagedConnectionFactory implementation that is responsible for satisfying this requirement.

Each injection of an object corresponds to a JNDI lookup. Whether a new instance of the requested object is injected, or whether a shared instance is injected, is determined by the rules described above.

Annotations for Environment Entries

A field or method of a bean class may be annotated to request that an entry from the bean's environment be injected. Any of the types of resources or other environment entries described in this chapter may be injected. Injection may also be requested using entries in the deployment descriptor corresponding to each of these resource types. The field or method MAY have any access qualifier (public, private, etc.) but MUST NOT be static.

Each resource may only be injected into a SINGLE field or method of the bean. Requesting injection of the java:comp/env/com.example.MySessionBean/myDatabase resource into both the setMyDatabase method and the myDatabase instance variable is an ERROR. Note, however, that either the field or the method could request injection of a resource of a different (non-default) name. By explicitly specifying the JNDI name of a resource, a single resource may be injected into MULTIPLE fields or methods of multiple classes.

Annotations may also be applied to the bean class itself. These annotations declare an entry in the bean's environment, but do not cause the resource to be injected. Instead, the bean is expected to use the EJBContext lookup method or the methods of the JNDI API to lookup the entry. When the annotation is applied to the bean class, the JNDI name and the environment entry type MUST be explicitly specified.

Annotations may appear on the bean class, or on any superclass. A resource annotation on any class in the inheritance hierarchy defines a resource needed by the bean. However, injection of such resources follows the Java language overriding rules for the visibility of fields and methods. A method definition that overrides a method on a superclass defines the resource, if any, to be injected into that method. An overriding method may request injection of a different resource than is requested by the superclass, or it may request no injection even though the superclass method requests injection.

In addition, fields or methods that are not visible in or are hidden (as opposed to overridden) by a subclass may still request injection. This allows, for example, a private field to be the target of injection and that field to be used in the implementation of the superclass, even though the subclass has no visibility into that field and doesn't know that the implementation of the superclass is using an injected resource. Note that a declaration of a field in a subclass with the same name as a field in a superclass always causes the field in the superclass to be hidden.

Annotations and Deployment Descriptors

Environment entries may be declared by the use of annotations, without need for any deployment descriptor entries. Environment entries may also be declared by deployment descriptor entries, without need for any annotations. The same environment entry may be declared using both an annotation and a deployment descriptor entry. In this case, the information in the deployment descriptor entry may be used to override some of the information provided in the annotation. This approach may be used by an Application Assembler to override information provided by the Bean Provider. Deployment descriptor entries should not be used to request injection of a resource into a field or method that has not been designed for injection.

The following rules apply to how a deployment descriptor entry may override a Resource annotation:

Restrictions on the overriding of environment entry values depend on the type of environment entry.

EJB References

Injection of EJB References

The Bean Provider uses the EJB annotation to annotate a field or setter property method of the bean class as a target for the injection of an EJB reference. The reference may be to a session bean's business interface or to the local home interface or remote home interface of a session bean or entity bean.

The following example illustrates how an enterprise bean uses the EJB annotation to reference another enterprise bean. The enterprise bean reference will have the name java:comp/env/com.acme.example.ExampleBean/myCart in the referencing bean's naming context, where ExampleBean is the name of the class of the referencing bean and com.acme.example its package. The target of the reference must be resolved by the Deployer.

package com.acme.example;

@Stateless public class ExampleBean implements Example {
	@EJB private ShoppingCart myCart;
	...
}					
					

The following example illustrates use of all portable elements of the EJB annotation. In this case, the enterprise bean reference would have the name java:comp/env/ejb/shopping-cart in the referencing bean's naming context. This reference is linked to a bean named cart1.

@EJB(
	name="ejb/shopping-cart",
	beanInterface=ShoppingCart.class,
	beanName="cart1",
	description="The shopping cart for this application"
)
private ShoppingCart myCart;					
					

If the ShoppingCart bean were instead written to the EJB 2.1 client view, the EJB reference would be to the bean's home interface. For example:

@EJB(
	name="ejb/shopping-cart",
	beanInterface=ShoppingCartHome.class,
	beanName="cart1",
	description="The shopping cart for this application"
)
private ShoppingCartHome myCartHome;					
					

EJB Reference Programming Interfaces

The Bean Provider may use EJB references to locate the business interfaces or home interfaces of other enterprise beans as follows.

The following example illustrates how an enterprise bean uses an EJB reference to locate the remote home interface of another enterprise bean using the JNDI APIs:

@EJB(name="ejb/EmplRecord", beanInterface=EmployeeRecordHome.class)
@Stateless 
public class EmployeeServiceBean implements EmployeeService {
	public void changePhoneNumber(...) {
	// Obtain the default initial JNDI context.
	Context initCtx = new InitialContext();
	
	// Look up the home interface of the EmployeeRecord
	// enterprise bean in the environment.
	Object result = initCtx.lookup("java:comp/env/ejb/EmplRecord");
	
	// Convert the result to the proper type.
	EmployeeRecordHome emplRecordHome = (EmployeeRecordHome)
		javax.rmi.PortableRemoteObject.narrow(result, EmployeeRecordHome.class);		
	...
	}
}					
					

In the example, the Bean Provider of the EmployeeServiceBean enterprise bean assigned the environment entry ejb/EmplRecord as the EJB reference name to refer to the remote home of another enterprise bean.

Declaration of EJB References in Deployment Descriptor

Although the EJB reference is an entry in the enterprise bean's environment, the Bean Provider must not use a env-entry element to declare it. Instead, the Bean Provider must declare all the EJB references using the ejb-ref and ejb-local-ref elements of the deployment descriptor. This allows the ejb-jar consumer (i.e. Application Assembler or Deployer) to discover all the EJB references used by the enterprise bean. Deployment descriptor entries may also be used to specify injection of an EJB reference into a bean.

Each ejb-ref or ejb-local-ref element describes the interface requirements that the referencing enterprise bean has for the referenced enterprise bean. The ejb-ref element is used for referencing an enterprise bean that is accessed through its remote business interface or remote home and component interfaces. The ejb-local-ref element is used for referencing an enterprise bean that is accessed through its local business interface or local home and component interfaces.

The ejb-ref element contains the description, ejb-ref-name, ejb-ref-type, home, and remote elements.

The ejb-local-ref element contains the description, ejb-ref-name, ejb-ref-type, local-home, and local elements.

The ejb-ref-name element specifies the EJB reference name: its value is the environment entry name used in the enterprise bean code. The ejb-ref-name MUST be specified. The optional ejb-ref-type element specifies the expected type of the enterprise bean: its value must be either Entity or Session. The home and remote or local-home and local elements specify the expected Java types of the referenced enterprise bean's interface(s). If the reference is to an EJB 2.1 remote client view interface, the home element is REQUIRED. Likewise, if the reference is to an EJB 2.1 local client view interface, the local-home element is REQUIRED. The remote element of the ejb-ref element refers to either the business interface type or the component interface, depending on whether the reference is to a bean's EJB 3.0 or EJB 2.1 remote client view. Likewise, the local element of the ejb-local-ref element refers to either the business interface type or the component interface, depending on whether the reference is to a bean's EJB 3.0 or EJB 2.1 local client view.

An EJB reference is scoped to the enterprise bean whose declaration contains the ejb-ref or ejb-local-ref element. This means that the EJB reference is NOT accessible to other enterprise beans at runtime, and that other enterprise beans may define ejb-ref and/or ejb-local-ref elements with the same ejb-ref-name WITHOUT causing a name conflict.

The following example illustrates the declaration of EJB references in the deployment descriptor:


<enterprise-beans>
	<session>
		<ejb-name>EmployeeService</ejb-name>
		<ejb-class>com.wombat.empl.EmployeeServiceBean</ejb-class>
		...
		<ejb-ref>
			<description>
				This is a reference to an EJB 2.1 entity bean that
				encapsulates access to employee records.
			</description>
			<ejb-ref-name>ejb/EmplRecord</ejb-ref-name>
			<ejb-ref-type>Entity</ejb-ref-type>
			<home>com.wombat.empl.EmployeeRecordHome</home>
			<remote>com.wombat.empl.EmployeeRecord</remote>
		</ejb-ref>
		
		<ejb-local-ref>
			<description>
				This is a reference to the local business interface
				of an EJB 3.0 session bean that provides a payroll
				service.
			</description>
			<ejb-ref-name>ejb/Payroll</ejb-ref-name>
			<local>com.aardvark.payroll.Payroll</local>
		</ejb-local-ref>
		
		<ejb-local-ref>
			<description>
				This is a reference to the local business interface
				of an EJB 3.0 session bean that provides a pension
				plan service.
			</description>
			<ejb-ref-name>ejb/PensionPlan</ejb-ref-name>
			<local>com.wombat.empl.PensionPlan</local>
		</ejb-local-ref>
		
	</session>
</enterprise-beans>
					
					

The Application Assembler can use the ejb-link element in the deployment descriptor to link an EJB reference to a target enterprise bean.

The Application Assembler specifies the link between two enterprise beans as follows:

The following illustrates an ejb-link in the deployment descriptor:


<enterprise-beans>
	<session>
		<ejb-name>EmployeeService</ejb-name>
		<ejb-class>com.wombat.empl.EmployeeServiceBean</ejb-class>
		...
		<ejb-ref>
			<ejb-ref-name>ejb/EmplRecord</ejb-ref-name>
			<ejb-ref-type>Entity</ejb-ref-type>
			<home>com.wombat.empl.EmployeeRecordHome</home>
			<remote>com.wombat.empl.EmployeeRecord</remote>
			<ejb-link>EmployeeRecord</ejb-link>
		</ejb-ref>
		...
	</session>
	...
	<entity>
		<ejb-name>EmployeeRecord</ejb-name>
		<home>com.wombat.empl.EmployeeRecordHome</home>
		<remote>com.wombat.empl.EmployeeRecord</remote>
		...
	</entity>
	...
</enterprise-beans>
					
					

The Application Assembler uses the ejb-link element to indicate that the EJB reference EmplRecord declared in the EmployeeService enterprise bean has been linked to the EmployeeRecord enterprise bean.

The following example illustrates using the ejb-link element to indicate an enterprise bean reference to the ProductEJB enterprise bean that is in the same Java EE application unit but in a DIFFERENT ejb-jar file:


<entity>
	...
	<ejb-name>OrderEJB</ejb-name>
	<ejb-class>com.wombat.orders.OrderBean</ejb-class>
	...
	<ejb-ref>
		<ejb-ref-name>ejb/Product</ejb-ref-name>
		<ejb-ref-type>Entity</ejb-ref-type>
		<home>com.acme.orders.ProductHome</home>
		<remote>com.acme.orders.Product</remote>
		<ejb-link>../products/product.jar#ProductEJB</ejb-link>
	</ejb-ref>
	...
</entity>
					
					

The following example illustrates using the ejb-link element to indicate an enterprise bean reference to the ShoppingCart enterprise bean that is in the same Java EE application unit but in a DIFFERENT ejb-jar file. The reference was originally declared in the bean's code using an annotation. The Application Assembler provides ONLY the link to the bean:


...
<ejb-ref>
	<ejb-ref-name>ShoppingService/myCart</ejb-ref-name>
	<ejb-link>../products/product.jar#ShoppingCart</ejb-link>
</ejb-ref>
					
					

Resource Manager Connection Factory References

A resource manager connection factory is an object that is used to create connections to a resource manager. For example, an object that implements the javax.sql.DataSource interface is a resource manager connection factory for java.sql.Connection objects that implement connections to a database management system.

A field or a method of an enterprise bean may be annotated with the Resource annotation. The authenticationType and shareable elements of the Resource annotation may be used to control the type of authentication desired for the resource and the shareability of connections acquired from the factory.

The following code example illustrates how an enterprise bean uses annotations to declare resource manager connection factory references.

//The employee database.
@Resource javax.sql.DataSource employeeAppDB;
...
public void changePhoneNumber(...) {
	...
	// Invoke factory to obtain a resource. The security
	// principal for the resource is not given, and
	// therefore it will be configured by the Deployer.
	java.sql.Connection con = employeeAppDB.getConnection();
	...
}
					

The Bean Provider must use resource manager connection factory references to obtain connections to resources as follows.

The Bean Provider can control the shareability of the connections acquired from the resource manager connection factory. By default, connections to a resource manager are shareable across other enterprise beans in the application that use the same resource in the same transaction context. The Bean Provider can specify that connections obtained from a resource manager connection factory reference are not shareable by specifying the value of the shareable annotation element to false or the res-sharing-scope deployment descriptor element to be Unshareable. The sharing of connections to a resource manager allows the container to optimize the use of connections and enables the container's use of local transaction optimizations.

The Bean Provider has two choices with respect to dealing with associating a principal with the resource manager access:

The Bean Provider uses the authenticationType annotation element or the res-auth deployment descriptor element to indicate which of the two resource manager authentication approaches is used.

The following code sample illustrates obtaining a JDBC connection when the EJBContext lookup method is used:

@Resource(name="jdbc/EmployeeAppDB", type=javax.sql.DataSource)
@Stateless public class EmployeeServiceBean implements EmployeeService {
	@Resource SessionContext ctx;
	public void changePhoneNumber(...) {
		...
		// use context lookup to obtain resource manager
		// connection factory
		javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup("jdbc/EmployeeAppDB");
		
		// Invoke factory to obtain a connection. The security
		// principal is not given, and therefore
		// it will be configured by the Deployer.
		java.sql.Connection con = ds.getConnection();
		...
	}
}						
					

The following code sample illustrates obtaining a JDBC connection when the JNDI APIs are used directly:

@Resource(name="jdbc/EmployeeAppDB", type=javax.sql.DataSource)
@Stateless public class EmployeeServiceBean implements EmployeeService {
	EJBContext ejbContext;
	public void changePhoneNumber(...) {
		...
		// obtain the initial JNDI context
		Context initCtx = new InitialContext();
		
		// perform JNDI lookup to obtain resource manager
		// connection factory
		javax.sql.DataSource ds = (javax.sql.DataSource) initCtx.lookup("java:comp/env/jdbc/EmployeeAppDB");
		
		// Invoke factory to obtain a connection. The security
		// principal is not given, and therefore
		// it will be configured by the Deployer.
		java.sql.Connection con = ds.getConnection();
		...
	}
}
					

Although a resource manager connection factory reference is an entry in the enterprise bean's environment, the Bean Provider must not use an env-entry element to declare it.

Instead, if metadata annotations are not used, the Bean Provider must declare all the resource manager connection factory references in the deployment descriptor using the resource-ref elements. This allows the ejb-jar consumer (i.e. Application Assembler or Deployer) to discover all the resource manager connection factory references used by an enterprise bean. Deployment descriptor entries may also be used to specify injection of a resource manager connection factor reference into a bean.

Each resource-ref element describes a single resource manager connection factory reference. The resource-ref element consists of the description element; the mandatory res-ref-name element; and the optional res-type, res-auth and res-sharing-scope elements. The res-ref-name element contains the name of the environment entry used in the enterprise bean's code. The name of the environment entry is RELATIVE to the java:comp/env context (e.g., the name should be jdbc/EmployeeAppDB rather than java:comp/env/jdbc/EmployeeAppDB). The res-type element contains the Java type of the resource manager connection factory that the enterprise bean code expects. The res-type element is optional if an injection target is specified for the resource; in this case, the res-type defaults to the type of the injection target. The res-auth element indicates whether the enterprise bean code performs resource manager sign-on programmatically, or whether the container signs on to the resource manager using the principal mapping information supplied by the Deployer. The Bean Provider indicates the sign-on responsibility by setting the value of the res-auth element to Application or Container. If the res-auth element is not specified, Container sign-on is ASSUMED. The res-sharing-scope element indicates whether connections to the resource manager obtained through the given resource manager connection factory reference are to be shared or whether connections are unshareable. The value of the res-sharing-scope element is Shareable or Unshareable. If the res-sharing-scope element is not specified, connections are assumed to be SHAREABLE.

A resource manager connection factory reference is scoped to the enterprise bean whose declaration contains the resource-ref element. This means that the resource manager connection factory reference is not accessible from other enterprise beans at runtime, and that other enterprise beans may define resource-ref elements with the same res-ref-name without causing a name conflict.

The following example is the declaration of resource manager connection factory references used by the EmployeeService enterprise bean illustrated in the previous subsection:


<enterprise-beans>
	<session>
		<ejb-name>EmployeeService</ejb-name>
		<ejb-class>com.wombat.empl.EmployeeServiceBean</ejb-class>
		...
		<resource-ref>
			<description>
				A data source for the database in which
				the EmployeeService enterprise bean will
				record a log of all transactions.
			</description>
			<res-ref-name>jdbc/EmployeeAppDB</res-ref-name>
			<res-type>javax.sql.DataSource</res-type>
			<res-auth>Container</res-auth>
			<res-sharing-scope>Shareable</res-sharing-scope>
		</resource-ref>
		...
	</session>
</enterprise-beans>
					
					

The following example illustrates the declaration of JMS resource manager connection factory references:


<enterprise-beans>
	<session>
		...
		<resource-ref>
			<description>
				A queue connection factory used by the
				MySession enterprise bean to send
				notifications.
			</description>
			<res-ref-name>jms/qConnFactory</res-ref-name>
			<res-type>javax.jms.QueueConnectionFactory</res-type>
			<res-auth>Container</res-auth>
			<res-sharing-scope>Unshareable</res-sharing-scope>
		</resource-ref>
		...
	</session>
</enterprise-beans>
					
					

Resource Environment References

Resource environment references are special entries in the enterprise bean's environment. The Deployer binds the resource environment references to administered objects in the target operational environment.

A field or a method of a bean may be annotated with the Resource annotation to request injection of a resource environment reference. The authenticationType and shareable elements of the Resource annotation MUST NOT be specified; resource environment entries are NOT shareable and DO NOT require authentication. The use of the Resource annotation to declare a resource environment reference differs from the use of the Resource annotation to declare simple environment references only in that the type of a resource environment reference is not one of the Java language types used for simple environment references.

The Bean Provider must use resource environment references to locate administered objects that are associated with resources, as follows.

Although the resource environment reference is an entry in the enterprise bean's environment, the Bean Provider MUST NOT use a env-entry element to declare it. Instead, the Bean Provider must declare all references to administered objects associated with resources using either annotations in the bean's source code or the resource-env-ref elements of the deployment descriptor. This allows the ejb-jar consumer to discover all the resource environment references used by the enterprise bean. Deployment descriptor entries may also be used to specify injection of a resource environment reference into a bean.

Each resource-env-ref element describes the requirements that the referencing enterprise bean has for the referenced administered object. The resource-env-ref element contains optional description and resource-env-ref-type elements, and the MANDATORY resource-env-ref-name element. The resource-env-ref-type element is optional if an injection target is specified for the resource environment reference; in this case the resource-env-ref-type defaults to the type of the injection target.

The resource-env-ref-name element specifies the resource environment reference name: its value is the environment entry name used in the enterprise bean CODE. The name of the environment entry is relative to the java:comp/env context. The resource-env-ref-type element specifies the expected type of the referenced object.

A resource environment reference is scoped to the enterprise bean whose declaration contains the resource-env-ref element. This means that the resource environment reference is NOT accessible to other enterprise beans at runtime, and that other enterprise beans MAY define resource-env-ref elements with the SAME resource-env-ref-name without causing a name conflict.

Persistence Context References

Persistence context references are special entries in the enterprise bean's environment. The Deployer binds the persistence context references to container-managed entity managers for persistence contexts of the specified type and configured in accordance with their persistence unit.

A field or a method of an enterprise bean may be annotated with the PersistenceContext annotation. The name element specifies the name under which a container-managed entity manager for the referenced persistence unit may be located in the JNDI naming context. The OPTIONAL unitName element specifies the name of the persistence unit as declared in the persistence.xml file that defines the persistence unit. The OPTIONAL type element specifies whether a transaction-scoped or extended persistence context is to be used. If the type is not specified, a transaction-scoped persistence context will be used. References to container-managed entity managers with extended persistence contexts can ONLY be injected into stateful session beans. The OPTIONAL properties element specifies configuration properties to be passed to the persistence provider when the entity manager is created.

The following code example illustrates how an enterprise bean uses annotations to declare persistence context references:

@PersistenceContext(type=EXTENDED)
EntityManager em;					
					

The Bean Provider must use persistence context references to obtain references to a container-managed entity manager configured for a persistence unit as follows:

The following code sample illustrates obtaining an entity manager for a persistence context when the EJBContext lookup method is used:

@PersistenceContext(name="persistence/InventoryAppMgr")
@Stateless
public class InventoryManagerBean implements InventoryManager {
	@Resource SessionContext ctx;
	
	public void updateInventory(...) {
		...
		// use context lookup to obtain container-managed entity
		// manager
		EntityManager em =(EntityManager)
		ctx.lookup("persistence/InventoryAppMgr");
		...
	}
}					
					

The following code sample illustrates obtaining an entity manager when the JNDI APIs are used directly:

@PersistenceContext(name="persistence/InventoryAppMgr")
@Stateless
public class InventoryManagerBean implements InventoryManager {
	EJBContext ejbContext;
	
	public void updateInventory(...) {
		...
		// obtain the initial JNDI context
		Context initCtx = new InitialContext();
		
		// perform JNDI lookup to obtain container-managed entity
		// manager
		EntityManager em = (EntityManager)
			initCtx.lookup("java:comp/env/persistence/InventoryAppMgr");
		...
	}
}					
					

Although a persistence context reference is an entry in the enterprise bean's environment, the Bean Provider must not use an env-entry element to declare it.

Instead, if metadata annotations are not used, the Bean Provider MUST declare all the persistence context references in the deployment descriptor using the persistence-context-ref elements. This allows the ejb-jar consumer (i.e. Application Assembler or Deployer) to discover all the persistence context references used by an enterprise bean. Deployment descriptor entries may also be used to specify injection of a persistence context reference into a bean.

Each persistence-context-ref element describes a single container-managed entity manager reference. The persistence-context-ref element consists of the OPTIONAL description, persistence-unit-name, persistence-context-type and persistence-property elements, and the MANDATORY persistence-context-ref-name element.

The persistence-context-ref-name element contains the name of the environment entry used in the enterprise bean's CODE. The name of the environment entry is relative to the java:comp/env context (e.g., the name should be persistence/InventoryAppMgr rather than java:comp/env/persistence/InventoryAppMgr). The persistence-unit-name element is the name of the persistence unit, as specified in the persistence.xml file for the persistence unit. The persistence-context-type element specifies whether a transaction-scoped or extended persistence context is to be used. Its value is either Transaction or Extended. If the persistence context type is not specified, a transaction-scoped persistence context will be used. The optional persistence-property elements specify configuration properties that are passed to the persistence provider when the entity manager is created.

The following example is the declaration of a persistence context reference used by the InventoryManagerBean enterprise bean illustrated in the previous subsection:


<enterprise-beans>
	<session>
		<ejb-name>InventoryManagerBean</ejb-name>
		<ejb-class>com.wombat.empl.InventoryManagerBean</ejb-class>
		...
		<persistence-context-ref>
			<description>
				Persistence context for the inventory management
				application.
			</description>
			<persistence-context-ref-name>
				persistence/InventoryAppMgr
			</persistence-context-ref-name>
			<persistence-unit-name>
				InventoryManagement
			</persistence-unit-name>
		</persistence-context-ref>
	</session>
</enterprise-beans>
					
					

The Application Assembler can use the persistence-unit-name element in the deployment descriptor to specify a reference to a persistence unit. In this manner, multiple persistence units with the same persistence unit name may be uniquely identified when persistence unit names cannot be changed.

For example:


<enterprise-beans>
	<session>
		<ejb-name>InventoryManagerBean</ejb-name>
		<ejb-class>com.wombat.empl.InventoryManagerBean</ejb-class>
		...
		<persistence-context-ref>
			<description>
				Persistence context for the inventory management
				application.
			</description>
			<persistence-context-ref-name>
				persistence/InventoryAppMgr
			</persistence-context-ref-name>
			<persistence-unit-name>
				../lib/inventory.jar#InventoryManagement
			</persistence-unit-name>
		</persistence-context-ref>
	</session>
</enterprise-beans>
					
					

The Application Assembler uses the persistence-unit-name element to link the persistence unit name InventoryManagement declared in the InventoryManagerBean to the persistence unit named InventoryManagement defined in inventory.jar.

The following rules apply to how a deployment descriptor entry may override a PersistenceContext annotation:

Persistence Unit References

Persistence unit references are special entries in the enterprise bean's environment. The Deployer binds the persistence unit references to entity manager factories that are configured in accordance with the persistence.xml specification for the persistence unit.

A field or a method of an enterprise bean may be annotated with the PersistenceUnit annotation. The name element specifies the name under which the entity manager factory for the referenced persistence unit may be located in the JNDI naming context. The OPTIONAL unitName element specifies the name of the persistence unit as declared in the persistence.xml file that defines the persistence unit.

The following code example illustrates how an enterprise bean uses annotations to declare persistence unit references:

@PersistenceUnit
EntityManagerFactory emf;

@PersistenceUnit(unitName="InventoryManagement")
EntityManagerFactory inventoryEMF;
					

The Bean Provider must use persistence unit references to obtain references to entity manager factories as follows.

The following code sample illustrates obtaining an entity manager factory when the EJBContext lookup method is used:

@PersistenceUnit(name="persistence/InventoryAppDB")
@Stateless
public class InventoryManagerBean implements InventoryManager {
	@Resource SessionContext ctx;
	
	public void updateInventory(...) {
		...
		// use context lookup to obtain entity manager factory
		EntityManagerFactory emf = (EntityManagerFactory)
		ctx.lookup("persistence/InventoryAppDB");
		
		// use factory to obtain application-managed entity manager
		EntityManager em = emf.createEntityManager();
		...
	}
}					
					

The following code sample illustrates obtaining an entity manager factory when the JNDI APIs are used directly:

@PersistenceUnit(name="persistence/InventoryAppDB")
@Stateless
public class InventoryManagerBean implements InventoryManager {
	EJBContext ejbContext;

	public void updateInventory(...) {
		...
		// obtain the initial JNDI context
		Context initCtx = new InitialContext();
		
		// perform JNDI lookup to obtain entity manager factory
		EntityManagerFactory emf = (EntityManagerFactory) 
			initCtx.lookup("java:comp/env/persistence/InventoryAppDB");

		// use factory to obtain application-managed entity manager
		EntityManager em = emf.createEntityManager();
		...
	}
}					
					

Although a persistence unit reference is an entry in the enterprise bean's environment, the Bean Provider MUST NOT use an env-entry element to declare it.

Instead, if metadata annotations are not used, the Bean Provider must declare all the persistence unit references in the deployment descriptor using the persistence-unit-ref elements. This allows the ejb-jar consumer (i.e. Application Assembler or Deployer) to discover all the persistence unit references used by an enterprise bean. Deployment descriptor entries may also be used to specify injection of a persistence unit reference into a bean.

Each persistence-unit-ref element describes a single entity manager factory reference for the persistence unit. The persistence-unit-ref element consists of the optional description and persistence-unit-name elements, and the MANDATORY persistence-unit-ref-name element.

The persistence-unit-ref-name element contains the name of the environment entry used in the enterprise bean's CODE. The name of the environment entry is relative to the java:comp/env context (e.g., the name should be persistence/InventoryAppDB rather than java:comp/env/persistence/InventoryAppDB). The optional persistence-unit-name element is the name of the persistence unit, as specified in the persistence.xml file for the persistence unit.

The following example is the declaration of a persistence unit reference used by the InventoryManagerBean enterprise bean illustrated in the previous code sample:



<enterprise-beans>
	<session>
		<ejb-name>InventoryManagerBean</ejb-name>
		<ejb-class>com.wombat.empl.InventoryManagerBean</ejb-class>
		...
		<persistence-unit-ref>
			<description>
				Persistence unit for the inventory management
				application.
			</description>
			<persistence-unit-ref-name>
				persistence/InventoryAppDB
			</persistence-unit-ref-name>
			<persistence-unit-name>
				InventoryManagement
			</persistence-unit-name>
		</persistence-unit-ref>
		...
	</session>
</enterprise-beans>
					
					

The Application Assembler can use the persistence-unit-name element in the deployment descriptor to specify a reference to a persistence unit. The Application Assembler (or Bean Provider) may use the following syntax in the persistence-unit-name element of the referencing application component to avoid the need to rename persistence units to have unique names within a Java EE application. The Application Assembler specifies the path name of the root of the referenced persistence unit and appends the name of the persistence unit separated from the path name by #. The path name is relative to the referencing application component jar file. In this manner, multiple persistence units with the same persistence unit name may be uniquely identified when persistence unit names cannot be changed.

For example:


<enterprise-beans>
	<session>
		...
		<ejb-name>InventoryManagerBean</ejb-name>
		<ejb-class>com.wombat.empl.InventoryManagerBean</ejb-class>
		...
		<persistence-unit-ref>
			<description>
				Persistence unit for the inventory management
				application.
			</description>
			<persistence-unit-ref-name>
				persistence/InventoryAppDB
			</persistence-unit-ref-name>
			<persistence-unit-name>
				../lib/inventory.jar#InventoryManagement
			</persistence-unit-name>
		</persistence-unit-ref>
		...
	</session>
</enterprise-beans>
					
					

The Application Assembler uses the persistence-unit-name element to link the persistence unit name InventoryManagement declared in the InventoryManagerBean to the persistence unit named InventoryManagement defined in inventory.jar.

The following rules apply to how a deployment descriptor entry may override a PersistenceUnit annotation:

Professional hosting     Belorussian informational portal         Free SCWCD 1.4 Study Guide     Free SCDJWS 1.4 Study Guide     SCDJWS 1.4 Quiz     Free IBM Certified Associate Developer Study Guide     IBM Test 000-287. Enterprise Application Development with IBM WebSphere Studio, V5.0 Study Guide     Free Mock Exam Engine