Entity EJBs
This section describes the WebLogic Server value-added features for programming and using entity beans in applications, and provides associated design and development guidelines.
It is assumed that the reader is familiar with Java programming and entity bean features and capabilities. For an introduction to entity beans and how they are typically used in applications, see Entity EJBs Maintain Persistent Data and Entity Beans.
For a description of the overall bean development process, see Implementing Enterprise Java Beans.
These sections describe key entity bean features and capabilities.
- Using Primary Keys
- Using Container Managed Relationships
- Choosing a Concurrency Strategy
- Entity Bean Pooling and Caching
- CMP Entity Bean Descriptors Element by Feature
Using Primary Keys
Every entity EJB must have a primary key that uniquely identifies an entity bean within its home. Each entity bean instance may define a different class for its primary key; multiple entity beans can use the same primary key class, as appropriate.
If two entity bean instances have the same home and the same primary key, they are considered identical. A client can invoke the getPrimaryKey() method on the reference to an entity bean instance's remote interface to determine the instance's identity within its home.
The instance identity associated with a reference does not change during the lifetime of the reference. Therefore, the getPrimaryKey() method always returns the same value when called on the same entity object reference. A client that knows the primary key of an entity object can obtain a reference to the entity object by invoking the findByPrimaryKey(key) method on the bean's home interface.
Specifying Primary Keys and Primary Key Classes
You can map a primary key to one or multiple fields:
- Mapping a Primary Key to a Single CMP Field
In the entity bean class, you can have a primary key that maps to a single CMP field. CMP fields must be specified in both ejb-jar.xml and weblogic-cmp-jar.xml. In both descriptor files, CMP fields are specified in the cmp-field element. For simple primary keys, also specify the primary key in the primkey-field element in the ejb-jar.xml. In addition, specify the primary key field's class in the prim-key-class element in ejb-jar.xml.
- Wrapping One or More CMP Fields in a Primary Key Class
You can define your own primary key class that maps to single or multiple CMP fields. The primary key class must be public, and have a public constructor with no parameters. Specify the name of the primary key class in the prim-key-class element in ejb-jar.xml. All fields in the primary key class must be public, and must have the same names as the corresponding cmp-fields in ejb-jar.xml and weblogic-ejb-jar.xml. For compound primary keys, which map to multiple CMP fields, do not specify primkey-field in ejb-jar.xml.
- Anonymous Primary Key Class
If your entity EJB uses an anonymous primary key class, subclass the EJB and add a cmp-field of type java.lang.Integer to the subclass. Enable automatic primary key generation for the field so that the container fills in field values automatically, and map the field to a database column in the weblogic-cmp-jar.xml deployment descriptor.
Finally, update the ejb-jar.xml file to specify the EJB subclass, rather than the original EJB class, and deploy the bean to WebLogic Server.
Note: If you use the original EJB (instead of the subclass) with an anonymous primary key class, WebLogic Server displays the following error message during deployment:
In EJB ejb_name, an 'Unknown Primary Key Class' ( <prim-key-class> == java.lang.Object ) MUST be specified at Deployment time (as something other than java.lang.Object).
Guidelines for Specifying an Entity Bean's Primary Key
Follow these suggestions when using primary keys with WebLogic Server:
- Do not construct a new primary key class with an ejbCreate. Instead, allow the container to create the primary key class internally, as described in Automatically Generating Primary Keys.
- For a simple primary key - one composed of a single atomic value such as a String or an Integer - make the primary key class a container-managed field. Set the value of the primary key cmp-field using the setXXX methods within the ejbCreate method.
- Do not use a cmp-field of the type BigDecimal as a primary key field for CMP beans. The boolean BigDecimal.equals (object x) method considers two BigDecimal equal only if they are equal in value and scale. This is because there are differences in precision between the Java language and different databases. For example, the method does not consider 7.1 and 7.10 to be equal. Consequently, this method will most likely return false or cause the CMP bean to fail.
If you need to use BigDecimal as the primary key, you should:
- Implement a primary key class.
- In this primary key class, implement the boolean equal (Object x) method.
- In the equal method, use boolean BigDecimal.compareTo(BigDecimal val).
- If you are mapping a database column to a cmp-field and a cmr-field concurrently and the cmp-field is a primary key field, set the value when the ejbCreate() method is invoked by using the setXXX method for the cmp-field. The cmr-field is initialized automatically.
Automatically Generating Primary Keys
WebLogic Server supports automatic primary key generation feature for CMP entity beans. This feature is supported for simple (non-compound) primary keys only.
WebLogic Server supports two methods of automatic primary key generation:
- Native DMBS primary key generation - The database generates the primary key. To enable this feature, specify the database and a generator name in the <automatic-key-generation> stanza of weblogic-cmp-jar.xml. Based on the values you configure, the container generates code that obtains the primary key from the database. This feature is supported for Oracle and Microsoft SQL Server databases only. In addition, see the instructions in Declaring Primary Key Field Type
- Primary keys generated from a SEQUENCE table.
Whichever method of generated primary keys you use, see the instructions in Declaring Primary Key Field Type
Specifying Automatic Key Generation for Oracle
Generated primary key support for Oracle databases uses a SEQUENCE entity in the Oracle database to generate unique primary keys. The Oracle SEQUENCE is called when a new number is needed. Specify automatic key generation in the automatic-key-generation element in weblogic-cmp-jar.xml, as shown below.
<automatic-key-generation>
<generator-type>Oracle</generator-type>
<generator_name>test_sequence</generator-name>
<key-cache-size>10</key-cache-size>
</automatic-key-generation>Specify the name of the Oracle SEQUENCE in the generator-name element. If the Oracle SEQUENCE was created with a SEQUENCE INCREMENT, specify a key-cache-size. The value of key-cache-size must match the value of the Oracle SEQUENCE INCREMENT. If these two values are different, duplicate keys can result.
Note: Do not set the generator-type to USER_DESIGNATED_TABLE with Oracle. Doing so sets the TX ISOLATION LEVEL to SERIALIZABLE, which can cause the following exception:
javax.ejb.EJBException: nested exception is: java.sql.SQLException: Automatic Key Generation Error: attempted to UPDATE or QUERY NAMED SEQUENCE TABLE NamedSequenceTable, but encountered SQLException java.sql.SQLException: ORA-08177: can't serialize access for this transaction.
Instead, use the AutoKey option with Oracle.
Specifying Automatic Key Generation for Microsoft SQL Server
Generated primary key support for Microsoft SQL Server databases uses SQL Server's IDENTITY column. When the bean is created and a new row is inserted in the database table, SQL Server automatically inserts the next primary key value into the column that was specified as an IDENTITY column.
Note: For instructions on creating a SQL Server table that contains an IDENTITY column, see Microsoft documentation.
Once the IDENTITY column is created in the table, specify automatic key generation in weblogic-cmp-jar.xml as shown below.
<automatic-key-generation>
<generator-type>SQLServer</generator-type>
</automatic-key-generation>
Generating Primary Keys with a Named Sequence Table
A sequence table is a database-neutral way to generate primary keys. The sequence table holds a monotonically increasing integer sequence value that is used as the primary key value in bean instances as they are created.
Create a table named SEQUENCE to hold the current primary key value. The table consists of a single row with a single column, as defined by the following statement:
CREATE table_name (SEQUENCE int)
INSERT into table_name VALUES (0)To use this feature, make sure that the underlying database supports a transaction isolation level of Serializable. The Serializable value indicates that simultaneously executing a transaction multiple times has the same effect as executing the transaction multiple times in a serial fashion. This is important in a WebLogic Server cluster, in which multiple servers instances access the sequence table concurrently. See your database documentation to determine the isolation levels it supports.
Specify automatic key generation in the weblogic-cmp-jar.xml file, as shown below. In addition, see the instructions in Declaring Primary Key Field Type.
<automatic-key-generation>
<generator-type>NamedSequenceTable</generator-type>
<generator_name>MY_SEQUENCE_TABLE_NAME</generator-name>
<key-cache-size>100</key-cache-size>
</automatic-key-generation>Specify the name of the sequence table in the generator-name element.
Specify the size of the key cache - how many keys the container will fetch in a single DBMS call - in the key-cache-size element. BEA recommends a key-cache-size greater than one. This setting reduces the number of calls to the database to fetch the next key value.
BEA recommends that you define one NAMED SEQUENCE table per bean type. Beans of different types should not share a common NAMED SEQUENCE table. This reduces contention for the key table.
Declaring Primary Key Field Type
For both native DBMS primary key generation, or key generation using a named sequence table, in the abstract get and set methods of the associated entity bean, declare the primary field type to be either:
- java.lang.Integer
- java.lang.Long
In weblogic-cmp-jar.xml, set the key-cache-size element to specify how many primary key values in the sequence should be fetched from the database at a time. For example, setting key_cache_size to 10 results in one database access for every 10 beans created, to update the sequence. The default value of key_cache_size is 1. BEA recommends that you set key_cache_size to a value greater than one, to minimize database accesses and to improve performance.
Support for Oracle SEQUENCE
WebLogic Server can automatically create an Oracle SEQUENCE - a number generator that generates a unique integer each time it is called.
An Oracle SEQUENCE can use a specified "increment value", which is the value by which the integer is incremented on each subsequent generation. For example, if a SEQUENCE generates the integer 24 and the increment value is 10, then the next integer the SEQUENCE generates will be 34.
Using Container Managed Relationships
You can define a relationship between two WebLogic Server entity beans whose data persist in the same database. Entities that participate in the same relationship must map to the same datasource. WebLogic Server does not support relationships between entity beans that are mapped to different datasources
Relationships allow you to associate beans that are involved in the same processing task, so you can cache them together, and reduce the number of queries necessary to perform the task. The EJB container maps the logical relationship to the physical database details at runtime, and ensures referential integrity. Relationships allow the EJB container to perform database updates in the correct order - avoiding data consistency problems - when batching database updates and applying them at the end of a transaction
When a bean instance that participates in a relationship is removed, the container automatically removes the relationship. For instance, given a relationship between an employee and a department, if the employee is removed, the container removes the relationship between the employee and the department as well.
Specifying Relationship Cardinality in ejb-jar.xml
An entity bean can have a one-to-one, one-to-many, or many-to-many relationship with another entity bean in the same .jar. The abstract schema for each bean that participates in a container-managed relationship must be defined the same ejb-jar.xml file.
Relationships are defined in the <ejb-relation> stanza of ejb-jar.xml. The <ejb-relation> stanza contains two <ejb-relationship-role> stanzas - one for each side of the relationship, including the cmr-field. The lack of a cmr-field element in an ejb-relationship-role stanza specifies that the relationship is unidirectional in navigability and the entity bean that participates in the relationship is "not aware" of the relationship.
Table 6-1 lists the contents of cmr-field for each bean in a relationship, based on the cardinality of the relationship.
If the cardinality between BeanA and BeanB is
BeanA's cmr-field contains...
BeanB's cmr-field contains...
one-to-one a local interface instance a local interface instance one-to-many a local interface instance a Collection of local interface instances many-to-many a Collection of local interface instances a Collection of local interface instances Note: If the cmr-field contains many elements, specify the cmr-field-type as java.util.Collection, as shown below:
<cmr-field>
<cmr-field-name>dogs</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>Otherwise, you do not need to specify cmr-field-type in ejb-jar.xml.
Relationship Directionality
- Unidirectional - One entity bean points to another, but the latter bean does not point to the first. Behaviors the relate to the relationships occur when the pointing bean is accessed, but not when the target bean is accessed.
For example, if you define a one-to-one, unidirectional relationship from Entity_A to Entity_B, when Entity_A is cached, so is Entity_B. Because the relationship is unidirectional, caching Entity_B does not cause Entity_A to also be cached.
Implement a unidirectional relationship by specifying a cmr-field element in the ejb-relationship-role stanza for the starting entity bean, but not in for the target bean.
- Bidirectional - One entity bean points to another, and the latter bean points at the first. Behaviors that relate to the relationships occur when the either of the beans is accessed.
For example, if you define a one-to-one, bidirectional relationship between Entity_A and Entity_B, when Entity_A is cached, so is Entity_B. Because the relationship is bidirectional, caching Entity_B similarly causes Entity_A to be cached.
Implement a bidirectional relationship by specifying a cmr-field element in the ejb-relationship-role stanza for both entity beans in the relationship.
Configuring Container-Managed Relationships in weblogic-cmp-jar.xml
Configure a container-managed relationship in the weblogic-rdbms-relation stanza, a child of weblogic-rdbms-jar stanza in weblogic-cmp-jar.xml.
<weblogic-rdbms-relation>
<relation-name>...</relation-name>
<weblogic-relationship-role>
<relationship-role-name>...</relationship-role-name>
<column-map>
<foreign-key-column>...</foreign-key-column>
<key-column>.../key-column>
/column-map>
/weblogic-relationship-role>
</weblogic-rdbms-relation>The weblogic-rdbms-relation stanza specifies:
- relation-name - which should be same as the ejb-relationship-role-name for the relationship in ejb-jar.xml.
- <column-map> - associates the foreign-key-column in the target bean's table to the targeting bean's key-column,its primary key.
For one-to-one relationships and one-to-many relationships, the mapping is from a foreign key in one bean's table to the primary key in another bean's table. For many-to-many relationships, the mapping involves a join table. Each row in the join table contains two foreign keys that map to the primary keys of the entities involved in the relation. Note that the direction of a relationship does not affect how you specify the database mapping for the relationship.
See these sections for examples:
- Defining a One-to-One Relationship
- Defining a One-to-Many Relationship
- Defining a Many-to-Many Relationship
About Relation Fields and Relation Field Accessor Methods
Relation fields are not stored as attributes of an implementation class - they are accessible in the bean through relation field accessor methods that you write. For remote clients, relation fields can be exposed in the remote interface only if they are not Collections.
Relation field accessor methods:
- must begin with get...() and set...() and the text following get.../set... must match the name of the relation field as it is declared in the ejb-jar.xml.
- must exist in the implementation class for every relation field.
- must be declared abstract
If you want clients to use the field accessor methods, put the getter and/or setter method signatures in the remote interface. You may only do this if the method does not access a Collection. Only the entity beans's business methods can use its own Collection relation fields.
Using Cascade Delete for Entities in CMRs
When a cascade delete is performed, the deletion of a bean instance that participates in a relationship with another bean instances causes the container to also automatically delete all of the dependent bean instances. This feature is an efficient way to maintain data integrity.
For example, if the Employee bean has a one-to-many relationship to the Employee_Projects bean, deleting an Employee bean instance causes instances of the Employee_Projects bean to also be deleted.
You can specify cascade delete for one-to-one and one-to-many relationships; many-to-many relationships are not supported.
WebLogic Server supports two methods of cascade delete:
- J2EE Cascade Delete - This method does not require that the underlying database have built-in support for cascade deletes. Configure the behavior using the cascade-delete element in ejb-jar.xml, as shown in the following example:
<ejb-relation>
<ejb-relation-name>Customer-Account</ejb-relation-name>
<ejb-relationship-role>
<ejb-relationship-role-name>Account-Has-Customer
</ejb-relationship-role-name>
<multiplicity>one</multiplicity>
<cascade-delete/>
</ejb-relationship-role>
</ejb-relation>Note: The cascade-delete element can only be specified for a ejb-relationship-role element if the other ejb-relationship-role in the relationship has multiplicity of one.
- Database-Level Cascade Delete (Oracle only) - This method allows an application to take advantage of a database's built-in support for cascade delete, and possibly improve performance. When db-cascade-delete is enabled, the underlying database must be set up for cascade deletes. For instructions and examples of setting up database cascade delete in WebLogic and Oracle, db-cascade-delete.
In a high volume transaction environment, transactions that use exclusive concurrency can encounter deadlocks when a transaction that performs a cascade delete needs access to the same entity bean as a transaction that does not perform a cascade delete. For information on how to avoid such deadlocks, see Preventing Deadlocks for Transactions that Use Exclusive Concurrency and Cascade Deletes.
Delaying Database Inserts
Because of timing issues that may occur when creating a CMP bean, WebLogic Server enables you to specify at what point during the bean creation process the bean is inserted into the database.
Why Delay Database Inserts?
You cannot set a cmr-field until the primary key value for the bean - which is set when ejbPostCreate is called - is available. Hence, you cannot set a cmr-field until ejbPostCreate. This factor in combination with other conditions can lead to these problems:
- Problem 1: Non-null foreign key constraint
If a database row is inserted after EJBCreate (that is, before ejbPostCreate), then the foreign key is given a null value. This is because foreign key columns are set when cmr-fields are set.
Solution: Set delay-insert-until in weblogic-cmp-jar.xml to ejbCreate, which causes the insert to be done immediately after the ejbCreate, and set the relationship during ejbPostCreate.
- Problem 2: Creating beans during ejbPostCreate
When a related bean is created, the database insert for that bean happens before the create call finishes. If the database row for the related bean contains a foreign key that refers to the current bean and the foreign key has a referential integrity constraint defined, the insert will fail if the current bean's database row has not been inserted yet.
Solution: Set delay-insert-until to ejbCreate so that the row for the current bean exists during the ejbPostCreate.
- Problem 3: Both Problem 1 and Problem 2 exist
Solution: Do not create related beans during ejbPostCreate. Create the current bean and after the creation is finished, create the related beans and set up relationships.
BEA recommends that applications always do this. Applications should never create related beans during creation of another bean.
Configuring Delayed Database Inserts
You can delay database inserts until the end of the EJBCreate method or EJBPostCreate method, using the delay-database-insert-until element in weblogic-cmp-jar.xml. To batch, order, and perform updates at the end of the transaction, set both enable-batch-operations and order-database-operations in weblogic-cmp-jar.xml to "y".
If you choose to delay database updates for a transaction that updates related beans, define the relationship between the beans in the weblogic-rdbms-relation of weblogic-cmp-jar.xml. Otherwise, database constraint errors may result when the EJB container attempts to perform the updates.
Dynamic Queries
Dynamic queries allow you to construct and execute EJB-QL queries programmatically in your application code.
Using dynamic queries provides the following benefits:
- The ability to create and execute new queries without having to update and deploy an EJB.
- The ability to reduce the size of the EJB's deployment descriptor file. This is because finder queries can be dynamically created instead of statically defined in the deployment descriptors.
Enabling Dynamic Queries
To enable dynamic queries:
- Set the enable-dynamic-queries element in the EJB's weblogic-ejb-jar.xml to True:
<enable-dynamic-queries>True</enable-dynamic-queries>
- Set standard method permissions to control access to dynamic queries by specifying the method-permission element in the ejb-jar.xml deployment descriptor file.
Setting method-permission for the createQuery() method of the weblogic.ejb.QueryHome interface controls access to the weblogic.ejb.Query object necessary to executes the dynamic queries.
If you specify method-permission for the createQuery() method, the method-permission settings apply to the execute and find methods of the Query class.
Executing Dynamic Queries
The following code sample demonstrates how to execute a dynamic query.
InitialContext ic=new InitialContext();
FooHome fh=(FooHome)ic.lookup("fooHome");
QueryHome qh=(QueryHome)fh;
String ejbql="SELECT OBJECT(e)FROM EmployeeBean e WHERE e.name='rob'"
Query query=qh.createQuery();
query.setMaxElements(10)
Collection results=query.find(ejbql);
Automatic Table Creation
To make iterative development easier, the WebLogic Server EJB container can be configured to automatically change the underlying table schema as entity beans change, ensuring that tables always reflect the most recent object relationship mapping.
Note: This feature is disabled when a server instance is running in production mode, as a production environment may require the use of more precise table schema definitions, for example, the declaration of foreign key constraints.
The behavior of this feature is configured with create-default-dbms-tables element in weblogic-cmp-jar.xml. Based on the how you configure the feature, the container will recreate the table during deployment.
To ensure that the container only changes tables it created, container-created tables include an extra column, called wls_temp.
The syntax of table creation statements (DDL) varies from database to database, so table creation may fail on databases that are not fully supported. If this occurs, create the tables manually.
Note: Sequence tables, join tables, and Oracle SEQUENCEs are supported.
Enabling Automatic Table Creation
Enable this feature using the create-default-dbms-tables element in weblogic-cmp-jar.xml. The behavior of this feature varies according to the value of the element, as described in the following table. The EJB container actions described in the table occur during deployment.
Setting <create-default-dbms-tables> to this value
Results in this behavior:
Disabled The EJB container takes no action when underlying table schema changes. This is the default value. CreateOnly For each CMP bean in the .jar, if there is no table in the database for the bean, the container attempts to create the table based on information found in the deployment descriptor, including join tables, sequence tables, and Oracle sequences. If table creation fails, a Table Not Found error is thrown, and the user must create the table manually. DropAndCreate For each CMP bean in the.jar:
- if table columns have not changed, no action is taken, and the existing data is preserved.
- if the columns have changed, then the container drops and recreates the table and all table data is lost.
DropAndCreate
AlwaysFor each CMP bean listed in the .jar, the container drops and creates the table whether or not columns have changed. AlterOrCreate For each CMP bean in the .jar:
- if the table exists, the container attempts to alter the table schema using the "ALTER TABLE" SQL command and the container saves the data.
- if the table does not exist, the container creates the table during deployment.
Note: Do not use AlterOrCreate if a new column is specified as a primary key or a column with null values is specified as the new primary key column.
BLOB and CLOB Column Support for Oracle
WebLogic Server supports Oracle Binary Large Object (BLOB) and Character Large Object (CLOB) DBMS columns for CMP entity beans.
WebLogic Server maps BLOBs to a cmp-field that has a byte array or serializable type. At this time, no support is available for mapping char arrays to a CLOB column.
Enabling Oracle BLOB/CLOB Support
As described in BLOB and CLOB Column Support for Oracle, WebLogic Server supports Oracle Binary Large Object (BLOB) and Character Large Object (CLOB) DBMS columns for CMP entity beans.
To enable BLOB/CLOB support:
- In the bean class, declare the variable.
- Edit the XML by declaring the dbms-column-type deployment descriptor in the weblogic-cmp-jar.xml file.
- Create the BLOB or CLOB in the Oracle database.
Specifying a BLOB Column Using the Deployment Descriptor
The following XML code shows how to specify a BLOB object using the dbms-column-type element in weblogic-cmp-jar-xml file.
<field-map>
<cmp-field>photo</cmp-field>
<dbms-column>PICTURE</dbms-column>
</dbms-column-type>OracleBlob</dbms-column-type>
</field-map>
Controlling Serialization for cmp-fields of type byte[] mapped to a OracleBlob
Prior to WebLogic Server 8.1 SP02, by default, cmp-field of type byte[] mapped to an OracleBlob were serialized. In WebLogic Server 8.1 SP02, by default, they are not.
To cause WebLogic Server to serialize cmp-fields of type byte[] mapped to an OracleBlob, set the serialize-byte-array-to-oracle-blob compatibility flag, which was introduced in WebLogic Server 8.1 SP02.
By default, the value of serialize-byte-array-to-oracle-blob is false - the container will persist the byte[] directly and not serialize it.
Specifying a CLOB Column Using the Deployment Descriptor
The following XML code shows how to specify a CLOB object using the dbms-column element in the weblogic-cmp-jar-xml file.
Figure 6-1 Specifying a CLOB object
<field-map>
<cmp-field>description</cmp-field>
<dbms-column>product_description</dbms-column>
<dbms_column-type>OracleClob</dbms-column-type>
</field-map>
Field Groups
A field group represents a subset of a bean's container-managed persistence (CMP) and container-managed relationship (CMR) fields. To improve performance, you can put related fields in a bean into groups that are faulted into memory together as a unit.
You can associate a group with a query or relationship, so that when a bean is loaded as the result of executing a query or following a relationship, only the fields mentioned in the group are loaded.
A special group named "default" is used for queries and relationships that have no group specified. By default, the default group contains all of a bean's CMP fields and any CMR fields that add a foreign key to the bean's table.
A field can belong to multiple groups. In this case, the getXXX() method for the field faults in the first group that contains the field.
Specifying Field Groups
As described in Field Groups, you can improve your application's performance by putting related fields in a bean into groups that are faulted into memory together as a unit.
You specify field groups in weblogic-cmp-jar.xml file, as in Figure 6-2:
Figure 6-2 Specifying field groups
<weblogic-rdbms-bean>
<ejb-name>XXXBean</ejb-name>
<field-group>
<group-name>medical-data</group-name>
<cmp-field>insurance</cmp-field>
<cmr-field>doctors</cmr-fields>
</field-group>
</weblogic-rdbms-bean>
Multiple Table Mapping
Multiple table mapping allows you to partition an entity bean's cmp-fields and cmr-fields and map them to multiple DBMS tables within a single database.
Tables that are mapped to a single entity bean must not have referential integrity constraints declared between their primary keys. Doing so may result in a runtime error upon bean removal.
Each table must contain one row for each bean. Each table contains the same number of rows and primary key value.
Configuring Multiple Table Mappings for CMP Fields
Configure multiple table mappings for cmp-fields, in a weblogic-rdbms-bean stanza of the EJB's weblogic-cmp-jar.xml file, as follows:
- Specify the following elements in the weblogic-cmp-jar.xml file:
- table-field-map element
- table-name element
- field-map element
The following sample XML shows an EJB that maps to a single DBMS table:
Figure 6-3 Mapping a single DBMS table
<table-name>TableName</table-name>
<field-map>
<cmp-field>name</cmp-field>
<dbms-column>name_in_tablename</dbms-column>
</field-map><field-map>
<cmp-field>street_address</cmp-field>
<dbms-column>street_address_in_tablename
</dbms_column>
</field-map>
<field-map>
<cmp-field>phone</cmp-field>
<dbms-column>phone_in_tablename</dbms-column>
</field-map>The following sample XML shows an EJB that maps to two different tables:
Figure 6-4 Mapping to two DBMS tables
<table-map> <table-name>TableName_1</table-name>
<field-map>
<!--Note `name'is the primary key field of this EJB -->
<cmp-field>name</cmp-field>
<dbms-column>name_in_tablename_1</dbms-column>
</field-map><field-map>
<cmp-field>street_address</cmp-field>
<dbms-column>street_address_in_tablename_1
</dbms-column>
</field-map> </table-map> <table-map>
<table-name>TableName_2</table-name>
<field-map>
<!--Note `name'is the primary key field of this EJB -->
<cmp-field>name</cmp-field>
<dbms-column>name_in_tablename_2</dbms-column>
</field-map>
<field-map>
<cmp-field>phone</cmp-field>
<dbms-column>phone_in_tablename_2</dbms-column>
</field-map>
</table-map>Note: As shown in the above XML sample for a table mapping, map the primary key field to each table's primary key column.
Configuring Multiple Table Mapping for CMR Fields
Configure multiple table mappings for cmr-fields, in a weblogic-relationship-role stanza of the EJB's weblogic-cmp-jar.xml file, as follows:
- Specify the following elements in the weblogic-cmp-jar.xml file:
- column-map element
- foreign-key-column element
- key-column element
- foreign-key-table element
- primary-key-table element
Note: Multiple table mappings for cmr-fields require that the foreign key needed to maintain a relationship be only one of the tables that constitutes the EJB.
The following sample XML shows multiple table mapping for cmr-fields for an EJB with an one-to-one relationship with another EJB:
Figure 6-5 Mapping EJBs with an one-to-one relationship
<column-map>
<foreign-key-column>foreign_key_1</foreign-key-column>
<key-column>key_1</key-column>
</column-map>
<foreign-key-column>foreign_key_2</foreign-key-column>
<key-column>key_2</key-column>
</column-map>The following sample XML shows the multiple table mapping for cmr-fields for an EJB with explicitly named foreign key columns:
Figure 6-6 Mapping foreign key columns in a relationship-role-name stanza
<relationship-role-map>
<foreign-key-table>
<table-name>TableName_2</table-name>
</foreign-key-table>
<column-map>
<foreign-key-column>foreign_key_1
</foreign-key-column>
<key-column>key_11</key-column>
</column-map>
<column-map
<foreign-key-column>foreign_key_2
</foreign-key-column>
<key-column>key_12</key-column>
</column-map>
</relationship-role-map>When mapping many-to-many relationships, consider the following:
- The table-name element that you specify in the weblogic-rdbms-relation element refers to a separate join table that you use to maintain foreign key - primary key pairs between related beans.
- In the table-column-map element's column-map, the key-column element value refers to the DBMS column in the EJB table and the foreign-key-column element refers to the DBMS column name in the join table which you specify by the value in the table-name element.
Ordering and Batching Operations
Multiple instances of the same container-managed persistence (CMP) entity bean are often changed in a single transaction. If the EJB container issues SQL for every CMP entity bean instance, updates can become a performance bottleneck.
The EJB batch operations features solves this problem by updating multiple entries in a database table in one batch of SQL statements. This can dramatically improve performance by doing multiple database inserts, deletes, or updates for CMP beans in one database round-trip.
To permit batch database inserts, updates or deletes, set the enable-batch-operations element in the weblogic-cmp-jar.xml file to True.
Operation Ordering
Database operation ordering prevents constraint errors by taking into account database dependencies, and ordering inserts, updates and deletes accordingly.
Enabling database ordering causes the EJB container to do two things:
- Delay all database operations - insert, update, and delete - to commit time
- Order database operations at commit time
For example, assume a Customer A, who is related to Salesman A. If Salesman A is deleted, and Customer A is assigned to Salesman B, the container would order the operations in this fashion:
- Update Customer A to refer to Salesman B.
- Remove Salesman A.
This ensures that Customer A never refers to a salesman that does not exist, which would cause a database referential integrity error.
To enable the EJB container to correctly order database operations for related beans, specify the relationship between the beans, in the weblogic-rdbms-relation of weblogic-cmp-jar.xml Otherwise, database constraint errors may result when the EJB container attempts to perform the updates.
Batch Operations Guidelines and Limitations
When using batch operations, set the boundary for the transaction, as batch operations only apply to the inserts, updates or deletes between transaction begin and transaction commit.
Batch operations only work with drivers that support the addBatch() and executeBatch() methods. If the EJB container detects unsupported drivers, it reports that batch operations are not supported and disables batch operations.
There are several limitations on using batch operations:
- You cannot use the Automatically Generating Primary Keys feature with batch operations if the generator-type is set to sybase or sqlServer. If you have enabled automatic primary key generation with either of these types, WebLogic Server automatically disables batch operations and issues a warning.
- The total number of entries created in a single batch operation cannot exceed the max-beans-in-cache setting, which is specified in the weblogic-ejb-jar.xml file.
- If you set the dbms-column-type element in weblogic-cmp-jar.xml to either OracleBlob or OracleClob, batch operation automatically turns off because you will not save much time if a Blob or Clob column exist in the database table. In this case, WebLogic Server performs one insert per bean, which is the default behavior.
Read-Mostly Pattern
For persistent data that is only occasionally updated, you can implement a "read-mostly pattern" in WebLogic Server by mapping a read-only and a read-write entity bean to the same data. Use the read-only entity bean for reads and the read-write entity bean for writes.
The read-only entity EJB loads bean data at intervals specified by the read-timeout-seconds element in the entity-cache (or entity-cache-ref) stanza for the bean in weblogic-ejb-jar.xml. To ensure that the read-only bean always returns current data, the read-only bean must be must invalidated when the read-write bean changes the entity bean data. You can configure WebLogic Server to automatically invalidate the read-only bean, or explicitly invalidate it in bean code, as described in Invalidating Read-Only Entity EJBs Implicitly and Invalidating Read-Only Entity EJBs Explicitly respectively.
In a WebLogic Server cluster, the read-mostly pattern gives clients of the read-only EJB the performance advantage of reading from cache, while clients of read-write EJB enjoy true transactional behavior - the read-write EJB's cached state always matches the persistent data in the database.
Configuring Entity Beans for Read-Mostly Pattern
These practices will reduce the likelihood of data consistency problems with the read-mostly pattern.
- Configuring the read-only beans' read-timeout-seconds:
- to the same value in all beans that can be updated in the same transaction.
- to the shortest period that yields acceptable performance levels.
- Design read-write beans:
- to update the minimum data set necessary; avoid implementing beans that write numerous, unchanged fields to the datastore at each ejbStore().
- to update their data on a timely basis; do not use a read-write bean in lengthy transactions that might run longer than the read-timeout-seconds setting for its read-only counterparts.
- to invalidate the read-only counterpart of a read-write bean when the read-write bean updates bean data.
If you are running EJB 2.0, you can approximate the read-mostly pattern using a single bean that uses optimistic concurrency. An optimistic bean acts like a read-only beans when performing a read - it reads from the cache and can return stale data. However, when an optimistic bean performs a write, the container ensures that the data being updated has not changed - providing the same level of consistency for writes as a bean that uses Database concurrency. See Choosing a Concurrency Strategy.
Invalidating Read-Only Entity EJBs Implicitly
The invalidation-targetelement in the entity-descriptor stanza in weblogic-ejb-jar.xml identifies a read-only entity EJB that should be invalidated when a CMP entity bean has been modified.
invalidation-target may only be specified for an EJB 2.0 CMP entity bean.The target ejb-name must be a read-only entity EJB.
Invalidating Read-Only Entity EJBs Explicitly
Invalidate a read-only entity bean by calling the following invalidate() method on either the CachingHome or CachingLocalHome interface:
Figure 6-7 Sample code showing CachingHome and CachingLocalHome interfaces
package weblogic.ejb;public interface CachingHome {public void invalidate(Object pk) throws RemoteException;
public void invalidate (Collection pks) throws RemoteException;
public void invalidateAll() throws RemoteException;public interface CachingLocalHome {public void invalidate(Object pk) throws RemoteException;
public void invalidate (Collection pks) throws RemoteException;
public void invalidateAll() throws RemoteException}The following example codes shows how to cast the home to CachingHome and then call the method:
Figure 6-8 Sample code showing how to cast the home and call the method
import javax.naming.InitialContext;
import weblogic.ejb.CachingHome;Context initial = new InitialContext();
Object o = initial.lookup("CustomerEJB_CustomerHome");
CustomerHome customerHome = (CustomerHome)o;CachingHome customerCaching = (CachingHome)customerHome;
customerCaching.invalidateAll();The invalidate() method causes the read-only entity beans to be invalidated in the local server instance. If the server instance is a member of a cluster, it multicasts a message to the other clustered servers to invalidate their cached copies of the bean. Upon the next getXXX() to an invalidated read-only entity bean, the container loads the current version of the bean's persistent data to the entity cache from the database, as described in Understanding ejbLoad() and ejbStore() Behavior.
WebLogic Server calls invalidate() after the update transaction update has completed. If the invalidation occurs during a transaction update, the previous version might be read if the isolation-level for transactions does not permit reading uncommitted data.
Avoid Flushing the CMP Cache before Query Execution to Improve Performance
According to the EJB specification, updates made by a transaction must be reflected in the results of query-finders and ejbSelects issued during the transaction. This requirement can slow performance. You can use the include-updates element in weblogic-cmp-jar.xml to specify that the cache not be flushed before the query is executed.
Whether you use this feature depends on whether performance is more important than seeing the most current data. Setting include-updates to False provides the best performance; setting it to True provides more current and consistent data.
If this option is turned off, the updates of the current transaction are not reflected in the query. If this option is turned on - the default behavior - the container flushes all changes for the transactions to the database before executing the new query. This way, the changes show up in the results.
You can safely turn flushing off if your transactions do not re-query modified data - a common scenario - and get the best performance.
Note: In releases prior to WebLogic Server 8.1, the default for include-updates was False. For purposes of J2EE compliance, the default has been changed to True in WebLogic Server 8.1.
Specifying CMP Cache Flushing
The following code sample specifies that transaction results be reflected in the query, by setting include-updates to True.
Figure 6-9 Specifying that results of transactions be reflected in the query
<weblogic-query>
<query-method>
<method-name>findBigAccounts</method_name>
<method-params>
<method-param>double</method-param>
</method-params>
</query-method>
<weblogic-ql>WHERE BALANCE>10000 ORDERBY NAME</weblogic-ql>
<include-updates>True</include-updates>
</weblogic-query>
Understanding ejbLoad() and ejbStore() Behavior
This section describes how and when the persistent data for a CMP 2.0 entity bean is loaded to cache and written back to persistent storage.
- findXXX() - By default, calling a finder method on a CMP bean results in immediate load of the bean's persistent data to cache. This behavior is controlled by finders-load-bean element in the persistence stanza of weblogic-ejb-jar.xml.
- ejbLoad() - For CMP 2.0 entity beans, ejbLoad() causes a "lazy" load of a bean's persistent data to the entity cache when the next getXXX() for the bean's data is called. Hence, when a transaction is initiated for a CMP 2.0 entity bean instance, WebLogic Server reads the bean's data from the entity cache, rather than the database, unless ejbLoad() has been called since the bean was last loaded to cache.
By default, WebLogic Server calls ejbLoad() each time a new transaction is initiated for the entity bean
Note: When used with CMP 1.1 entity beans and entity beans that use bean-managed persistence, ejbLoad() does note perform the a lazy load - for these bean types, the bean's persistent data is loaded to cache during the ejbLoad()
- ejbStore() - WebLogic Server writes the persistent fields of an entity EJB to the database using calls to ejbStore().
By default, WebLogic Server calls ejbStore() when the transaction commits.
Controlling the Behavior of ejbLoad() and ejbStore()
For applications in which multiple clients can currently access and modify a bean's underlying data, the default behavior of ejbLoad() and ejbStore() described in Understanding ejbLoad() and ejbStore() Behavior ensures database integrity by:
- ensuring that each new transaction uses the latest version of the EJB's persistent data, and
- updating the database upon transaction commitment.
However, depending on your requirements, you may prefer to call ejbLoad() and ejbStore() either more or less frequently.
For instance, you might want to limit calls that access the database for performance reasons. If you application does not allow multiple transactions to concurrently access the EJB - for example, if the bean uses Exclusive concurrency - loading the data at the beginning of each transaction is unnecessary. Given that no other clients or systems update the EJB's underlying data, the cached EJB data is always up-to-date, and calling ejbLoad() results in extra overhead. In such cases, you can safely reduce calls to ejbLoad(), as described in Limiting Database Reads with cache-between-transactions (Long-Term Caching).
Alternatively, you might want to deviate from the standard ejbStore() behavior, by calling it before a transaction commits, in order to access and use intermediate transaction results. For instructions, see Updating the Database Before Transaction Ends.
Limiting Database Reads with cache-between-transactions (Long-Term Caching)
As described in Understanding ejbLoad() and ejbStore() Behavior, by default, WebLogic Server calls ejbLoad() each time a transaction is initiated for an entity bean.
You can configure WebLogic Server to call ejbLoad() only when a client first references the bean, rather than at the beginning of each transaction, by setting the cache-between-transactions element in the bean's entity-cache (or entity-cache-ref) stanza in weblogic-ejb-jar.xml to true. By default, cache-between-transactions is false.
When cache-between-transactions is true, WebLogic Server calls ejbLoad() for the bean only when a client first references the EJB, or when a transaction is rolled back. This behavior is referred to as long-term caching.
Long-term caching is allowed only if the concurrency-strategy for a bean is Exclusive, ReadOnly, or Optimistic. When long-term caching is configured for a:
- ReadOnly bean, WebLogic Server ignores the value of the cache-between-transactions. WebLogic Server always performs long-term caching of read-only data, regardless of the value of cache-between-transactions.
- Exclusive bean, the EJB container must have exclusive update access to the underlying data: the data must not be updated by another application outside of the EJB container.
Note: If a bean with Exclusive concurrency is deployed in a cluster long-term caching is automatically disabled because any server instance in the cluster may update the bean data.
- Optimistic bean, the EJB container reuses cached data for each transaction after the client first references the bean, but ensures that updates are transactionally consistent by checking for optimistic conflicts at the end of each transaction.
Note: In a cluster, when a bean with Optimistic concurrency is updated, notifications are broadcast to other cluster members to prevent optimistic conflicts.
Updating the Database Before Transaction Ends
As described in Understanding ejbLoad() and ejbStore() Behavior, by default, WebLogic Server calls ejbStore() only when the transaction commits.
To make intermediate results of uncommitted transactions available to other database users, set delay-updates-until-end-of-tx in the persistence element of weblogic-ejb-jar.xml to False - this causes WebLogic Server to call ejbStore() after each method call.
Note: While setting delay-updates-until-end-of-tx to false results in database updates after each method call, the updates are not committed until the end of the transaction.
Choosing a Concurrency Strategy
An entity bean's concurrency strategy specifies how the EJB container should manage concurrent access to the bean; it determines how and when WebLogic Server synchronizes its cached copy of the entity with the database.
Concurrency strategies supported by WebLogic Server are described in the following sections.
Exclusive Concurrency
With exclusive concurrency, the container places an exclusive lock on cached EJB instances when the bean is associated with a transaction. Other requests for the EJB instance are blocked until the transaction completes. Exclusive locks are local to the server instance, so this strategy is most appropriate for a single server architecture. When used in a cluster, exclusive concurrency serializes all requests to a bean instance within a server instance, but concurrency between servers in the cluster that access the same bean concurrently is governed by the database.
Multiple clients can use the exclusive concurrency option to access entity EJBs in a serial fashion. Using this exclusive option means that if two clients simultaneously attempt to access the same entity EJB instance (an instance having the same primary key), the second client is blocked until the EJB is available.
Database Concurrency
Without database concurrency, concurrency control for an EJB for each transaction is deferred to the underlying datastore. WebLogic Server allocates a separate entity bean instance to each transaction and allows concurrency control to be handled by the database. This is the default option.
With the Database mechanism, the EJB container continues to cache instances of entity bean instances. However, the container does not cache the intermediate state of a bean instance between transactions. Instead, WebLogic Server issues a SQL SELECT for each instance at the beginning of a transaction to obtain the latest EJB data. A SQL UPDATE is issued if there are changes.
The request to commit data is subsequently passed along to the database. The database, therefore, handles all concurrency control and deadlock detection for the EJB's data.
Optimistic Concurrency
As with the Database concurrency strategy, Optimistic concurrency gives each transaction its own bean instance. The Optimistic concurrency strategy does not hold any locks in the EJB container or the database while the transaction is in process.
Note: For databases that do read-locking (non-Oracle databases) optimistic beans read data in a separate, local transaction. The local transaction commits a soon as the read completes. This strategy avoids read locks and can allow for better scalability when transactions do not update the same data concurrently.
Check Data for Validity with Optimistic Concurrency
You can configure the EJB container to validate an Optimistic bean's transaction data before committing the transaction, to verify that no data read or updated by the transaction has bean changed by another transaction. If it detects changed data, the EJB container rolls back the transaction. Note that the EJB container does not validate Blob or Clob fields in a bean with Optimistic concurrency. The workaround is to use version or timestamp checking.
Configure validity checking for a bean with Optimistic concurrency using the verify-columns and verify-rows elements in the table-name stanza for the bean in weblogic-cmp-jar.xml file.
The verify-columns element specifies how columns in a table are checked for validity when you use the optimistic concurrency strategy.
- Set the value of the verify-columns element to:
- Read - to check all columns in the table that have been read during the transaction. This includes both rows that are simply read and rows that are read and then updated or deleted by the transaction.
- Modified - to check only the columns that have been updated or deleted by the current transaction.
- Version - to check that a version column exists in the table and that this column is used to implement optimistic concurrency.
A version column must be created with an initial value of 0, and must increment by 1 whenever the row is modified.
- Timestamp - to check that a timestamp column exists in the table and that this column is used to implement optimistic concurrency. Timestamp-based optimistic concurrency requires a 1 second granularity for the database column.
The EJB container manages the version and timestamp columns and ensures that these columns are kept up to date. Note that the version or timestamp column is not updated if the transaction did not modify and regular CMP or CMR fields - if the only data changed during the transaction was the value of the version or timestamp column (as a result of transaction initiation) the column used for optimistic checking will not be updated at the end of the transaction.
- Set the verify-rows element to:
- Read - to check all rows in the table that have been read during the transaction. This includes both rows that are simply read and rows that are read and then updated or deleted by the transaction. This entails additional overhead since it generally increases the amount of optimistic checking that must be performed by the EJB container. With the Read option, committed transactions read a set of rows that are guaranteed not to be modified by another transaction until after the transaction commits. This results in a high level of consistency which is very close to the ANSI definition of SERIALIZABLE consistency.
Note: If verify-rows is set to Read then the verify-columns element may not have a value of Modified since this combination would result in only checking the modified rows.
- Modified - to check only the rows that have been updated or deleted by the current transaction. This setting ensures that two transactions will not update the same row concurrently, resulting in a lost update, but it allows reads and updates of different transactions to be interleaved. This results in a level of consistency that falls between the ANSI READ_COMMITTED and REPEATABLE_READ levels of consistency.
- If verify-columns is set to Version or Timestamp, specify the version or timestamp column using the optimistic-column in the table-map stanza in the weblogic-cmp-jar.xml file. Mapping this column to a cmp-field is optional.
The optimistic-column element identifies a database column that contains a version or timestamp value used to implement optimistic concurrency. This element is case maintaining, though not all databases are case sensitive. The value of this element is ignored unless verify-columns is set to Version or Timestamp.
If the EJB is mapped to multiple tables, optimistic checking is only performed on the tables that are updated during the transaction.
Read Only Concurrency
Used to signify that a bean is read-only. The container activates a new bean instance for each transaction so that requests proceed in parallel. WebLogic Server calls ejbLoad() for read-only beans based on the read-timeout-seconds parameter.
Prior to version WebLogic Server 8.1 SP02, EJBs that used ReadOnly concurrency were allowed to use create and remove operations. In WebLogic Server 8.1 SP02, create and remove operations are not allowed for EJBs that used ReadOnly concurrency, because this practice is discouraged, and to allow generation of more efficient code for read-only beans.
To support the pre-SP02 behavior and allow read-only beans to use create and remove operations, set the allow-readonly-create-and-remove element in weblogic-cmp-jar.xml.
Concurrency Strategy Trade-Offs
Concurrency strategies present a trade-off between performance and freshness of data. You should choose a concurrency strategy based on which of these factors weighs more heavily in your application. The trade-offs are summarized in Table 6-3.
Concurrency Strategy
Benefits
Risks and Limitations
When to Choose It
Database Deferring concurrency control to the database improves throughput, compared to exclusive concurrency, for concurrent access to data and provides deadlock detection. Risk of deadlock, as each transaction must obtain an update lock from the database. Mitigate deadlock risk by setting use-select-for-
update element in weblogic-cmp-jar.
xml. This causes the database to take out an exclusive lock when the read is done, avoiding the deadlock that can occur when a read lock is upgraded to an exclusive lock. Makes the bean more dependent on the database's lock policies, which might reduce the bean's portability.If the database concurrency control is sufficient for your application and you do not require additional features provided by the container. Note: The transaction isolation level setting is used in combination with Database concurrency to achieve the desired concurrency behavior.
Optimistic Provides the highest level of concurrent access, as it holds no locks in the EJB container or database during a transaction.
If multiple transactions are unlikely to attempt to modify the same application data at the same time. Exclusive Serializes access to EJB data in a single server (non-clustered environment) for a high level of consistency. Avoids deadlocks due to lock upgrades, and prevents unnecessary calls to ejbLoad() to refresh the bean instance's persistent fields. Performance degradation can result. Once a client has locked an EJB instance, other clients are blocked from the EJB's data, even those who require only read-access. To provides backwards compatibility for applications that rely on this strategy.For applications in which a high level of concurrency is essential, and more important that performance. Read Only N/A N/A N/A
Configuring Concurrency Strategy
Specify the concurrency mechanism for a bean by setting the concurrency-strategy element in the entity-cache stanza in weblogic-ejb-jar.xml. Because concurrency-strategy is defined at the bean level, different beans in the same application can use different concurrency strategies, as appropriate.
Figure 6-10 specifies the Optimistic concurrency strategy.
Figure 6-10 Sample XML specifying the concurrency strategy
<entity-descriptor>
<entity-cache>
...
<concurrency-strategy>Optimistic</concurrency-strategy>
</entity-cache>
...
</entity-descriptor>If you do not specify a concurrency-strategy, WebLogic Server uses Database concurrency by default.
Preventing Deadlocks for Transactions that Use Exclusive Concurrency and Cascade Deletes
In situations of high throughput, transactions that use an exclusive concurrency strategy can encounter deadlocks if a transaction that performs a cascade delete needs access to the same entity bean as a transaction that does not perform a cascade delete.
You can prevent such deadlocks with the lock-order element of weblogic-cmp-jar.xml deployment descriptor file. lock-order defines the order in which beans are locked during a cascade delete of related beans. Its value is an integer value. The bean with the lowest lock-order value is processed first, the bean with the next lowest lock-order value is processed next, and so on.
The locking order specified should be the same as the locking order used by other transactions in the application.
lock-order causes a cascade delete to lock bean instances in the same order as their other transactions. If the normal lock order is BeanA, then BeanB, specify this lock-order, and cascade delete will use it.
Entity Bean Pooling and Caching
WebLogic Server provides these features to improve performance and throughput for entity EJBs:
- Free pool - stores anonymous entity beans that are used for invoking finders, home methods, and creating entity beans.
- Cache - contains instances that have an identity - a primary key, or are currently enlisted in a transaction (READY and ACTIVE entity EJB instances).
The sections that follow describe the lifecycle of an entity bean instance, and how the container populates and manages the free pool and the cache. For an illustration, see Figure 6-11.
Pooling for Entity EJBs
If you specify a non-zero value for the initial-beans-in-free-pool element in weblogic-ejb-jar.xml, WebLogic Server populates the pool with the specified quantity of bean instances at startup.
The default value of initial-beans-in-free-pool is zero. Populating the free pool at startup improves initial response time for the EJB, because initial requests for the bean can be satisfied without generating a new instance.
An attempt to obtain an entity bean instance from the free pool will always succeed, even if the pool is empty. If the pool is empty, a new bean instance is be created and returned.
POOLED beans are anonymous instances, and are used for finders and home methods. The maximum number of instances the pool can contain is specified by the max-beans-in-free-pool element, in weblogic-ejb-jar.xml which set to 1,000 by default.
Caching for Entity EJBs
When a business method is called on a bean, the container obtains an instance from the pool, calls ejbActivate, and the instance services the method call.
A READY instance is in the cache, has an identity - an associated primary key, but is not currently enlisted in a transaction. WebLogic maintains READY entity EJB instances in least-recently-used (LRU) order. Current Beans in Cache field in the monitoring tab displays the count of active and ready beans.
The number of bean instances in cache is limited by the value of the max-beans-in-cache element in weblogic-ejb-jar.xml. The number of bean instances with the same primary key allowed in the cache varies by concurrency strategy:
- Exclusive - For beans that use exclusive concurrency, only a single instance with the same primary key can exist in the cache simultaneously.
- Database, Optimistic, and ReadOnly - For beans that use Database, Optimistic, or ReadOnly concurrency, multiple instances with the same primary key can exist in the cache simultaneously.
Removing Beans from Cache
READY entity EJB instances are removed from the cache when the space is needed for other beans. When a READY instance is removed from cache, ejbPassivate is called on the bean, and the container will try to put it back into the free pool.
When the container tries to return an instance to the free pool and the pool already contains max-beans-in-free-pool instances, the instance is discarded.
ACTIVE entity EJB instances will not be removed from cache until the transaction they are participating in commits or rolls back, at which point they will become READY, and hence eligible for removal from the cache.
Entity EJB Lifecycle Transitions
Figure 6-11 illustrates the EJB free pool and cache, and the transitions that occur throughout an entity bean instance's lifecycle.
Figure 6-11 Entity Bean Lifecycle
Controlling Entity Caching
These sections describe options for caching entity beans and for managing data consistency.
Application-Level versus Bean-Level Caching
Application-level caching - also known as "combined caching" - allows multiple entity beans that are part of the same J2EE enterprise application to share a single runtime cache. Application-level caching offers the following advantages:
- Reduces the number of entity bean caches, and hence the effort to configure the cache.
- Better utilization of memory and heap space, because of reduced fragmentation. For example, if a particular EJB home experiences a burst of activity, it can make use of all memory available to the combined cache, while other EJBs that use the cache are paged out. If two EJBs use different caches, when one bean's cache becomes full, the container cannot page out EJBs in the other bean's cache, resulting in wasted memory
- Simplifies management; combined caching enables a system administrator to tune a single cache, instead of many caches.
- Provides better scalability
Application-level caching is not the best choice, however, for applications that experience high throughput. Because one thread of control exists per cache at a time, high throughput can create a bottleneck situation as tasks compete for control of the thread.
For instructions on implementing application-level caching, see Enabling Caching Between Transactions.
Configuring Application-Level Caching
To configure an application-level cache:
- Verify that the weblogic-application.xml file is located in the META-INF directory of the EAR file.
- Provide an entry in the weblogic-application.xml file as follows:
<weblogic-application>
<ejb>
<entity-cache>
<entity-cache-name>large_account</entity-cache-name>
<max-cache-size>
<megabytes>1</megabytes>
</max-cache-size>
</entity-cache>
</ejb>
</weblogic_application>Use the entity-cache element to define a named application level cache that will be used to cache entity bean instances at runtime. There are no restrictions on the number of different entity beans that may reference an individual cache.
The sub-elements of entity-cache have the same basic meaning as they do in the weblogic-ejb-jar.xml deployment descriptor file.
- Specify an entity-descriptor element in weblogic-ejb-jar.xml.
The weblogic-application.xml deployment descriptor is documented in the Application.xml Deployment Descriptor Elements" section of Developing WebLogic Server Applications.
Caching Between Transactions and Concurrency Options
This sections describe concurrency options for caching entity beans between transactions.
Caching Between Transactions with Exclusive Concurrency
When you enable caching between transactions for an entity bean with an Exclusive concurrency strategy the EJB container must have exclusive update access to the underlying data. This means that another application outside of the EJB container must not be updating the data.
Note: If you deploy an EJB with an Exclusive concurrency strategy in a cluster, the container disables caching between transactions because any node in the cluster may update the data. This would make caching between transactions impossible.
Caching Between Transactions with Optimistic Concurrency
When you enable long term caching for an entity bean with an Optimistic concurrency strategy the EJB container reuses the cached values from previous transactions. The container ensures that the updates are transactionally consistent by checking for optimistic conflicts at the end of the transaction.
In addition, notifications for updates of optimistic data are broadcast to other cluster members to help avoid optimistic conflicts and keep cached data fresh.
Caching Between Transactions with Read-Only Concurrency
Caching between transactions is automatically enabled with a Read-Only concurrency strategy, because read-only entity beans never call ejbStore().
Enabling Caching Between Transactions
To enable caching between transactions:
- Set the cache-between-transactions element in the weblogic-ejb-jar.xml file by choosing one of the following options:
- Specify True to enable the EJB container performs long term caching of the data.
- Specify False to enable the EJB container to perform short term caching of the data. This is the default setting.
Caching between Transactions
A BMP bean using this concurrency strategy
Can set cache-between-transactions to...
Database False only Exclusive True or False Optimistic Not applicable. Optimistic concurrency is not available for BMP beans.
A CMP 2.0 bean using this concurrency strategy
Can set cache-between-transactions to this value
Database False only Exclusive True or False Optimistic True or False
A CMP 1.1 bean using this concurrency strategy
Can set cache-between-transactions to this value
Database False only Exclusive True or False Optimistic Not applicable. Optimistic concurrency is not available for CMP 1.1 beans.
Relationship Caching
Relationship caching - also known as "pre-fetching" or "eager relationship caching' - improves the performance of entity beans by loading related beans into the cache and preventing multiple queries by issuing a join query for the related bean. If a set of beans are accessed as part of the same unit of work, then your application should load them into cache at the same time.
Suppose your application contains entity beans with the following relationships:
customerBean has a one-to-many relationship with accountBean accountBean has a one-to-one relationship with addressBean customerBean has a one-to-one relationship with phoneBean
Consider the following EJB code for accountBean and addressBean, which have a 1-to-1 relationship:
Account acct = acctHome.findByPrimaryKey("103243");
Address addr = acct.getAddress();Without relationship caching, a SQL query is issued by the first line of code to load the accountBean and another SQL query is issued by the second line of code to load the addressBean; this results in two queries to the database.
With relationship caching, a single query is issued to load both the AccountEJB and AddressEJB by the first line of code, which should result in better performance. So, if you know that a related bean will be accessed after executing a particular finder method, its a good idea to let the finder method know via the relationship caching feature.
Note: The relationship caching feature has the following limitations:
- Relationship caching is supported for one-to-one, one-to-many, and many-to-one relationships. It is not supported for many-to-many relationships.
- When using weblogic-ql, this feature only works with finder methods that return references to either EJBObject or EJBLocalObject beans.
If you enable relationship caching for a finder or a select method, the result of the query will always be a distinct set even if the distinct keyword is not specified. This is due to a technical limitation that does not allow the EJB container to distinguish duplicates in the underlying JDBC result set.
Enabling Relationship Caching
To enable relationship caching:
- Specify the caching-name element in the weblogic-query stanza of the weblogic-cmp-jar.xml file.
If a caching-name element is specified in the weblogic-query stanza, when the finder query is executed, WebLogic Server loads data for related beans as specified by the relationship-caching element that the caching-name element specifies.
- Make sure that the finders-load-bean element (in weblogic-ejb-jar.xml) for the bean that contains the finder is not set to False or relationship caching will not be enabled. The default value of finder-load-bean is True.
- Specify the database-type element in weblogic-cmp-jar.xml file. Relationship caching uses outer joins for queries and outer join syntax can vary by database type.
Because relationship caching uses join queries, the number of caching-element stanzas in the relationship-caching element can increase duplicates in the result set. Specify one one-to-many relationships per caching-element to avoid duplicates in the result set.
Specify the relationship-caching stanza in weblogic-cmp-jar.xml, as shown in this example:
<relationship-caching>
<caching-name>cacheMoreBeans</caching-name>
<caching-element>
<cmr-field>accounts<</cmr-field>
<group-name>acct_group</group-name>
<caching-element>
<cmr-field>address</cmr-field>
<group-name>addr_group</group-name>
</caching-element>
</caching-element><caching-element>
<cmr-field>phone</cmr-field>
<group-name>phone_group</group-name>
</caching-element>
</relationship-caching>The accounts and phone fields are cmr-fields in customerBean; the address field is a cmr- field in the accountBean; and addr_group and phone_group are groups in addressBean and phoneBean.
Using nested caching-element elements enables the bean to load more than one level of related beans. In the above sample, addressBean is the second level related bean because it is nested in the accountBean. Currently, there is no limitation on the number of caching-elements that you can specify. However, setting too many caching-element levels could have an impact on the performance of the current transaction.
CMP Entity Bean Descriptors Element by Feature
The following sections are a quick reference to WebLogic Server-specific deployment for CMP entity beans. Each section contains the elements related to a particular the type of feature or behavior. The table in each section defines relevant elements terms of: the behavior it controls, the parent stanza in weblogic-cmp-jar.xml that contains the element, and the behavior you can expect if you do not explicitly specify the element in weblogic-cmp-jar.xml.
Container-Managed Relationship Elements
Element
Description
relation-name Name of the relationship. Note: If a ejb-relation-name for the relationship is specified in ejb-jar.xml, relation-name must contain the same value as ejb-relation-name.
relationship-role-name The name of the relationship role. (A relationship has two roles - one for each side of the relationship).For a 1-1 or 1-m relationship, specify only the role on the foreign-key side. For an examples, see Defining a One-to-One Relationship and Defining a One-to-Many Relationship.For a m:m relationship, specify the roles on both sides of the relationship. roles for both sides of the relationship are specified. For an example, see Defining a Many-to-Many Relationship. Note that the value of <relationship-role-
name> should match the name of an ejb-relationship-role in ejb-jar.xml.foreign-key-column Specifies the target side of the key column mapping for the relationship - the foreign key column. key-column Specifies the initiating side of the key column mapping for the relationship - the primary key column.
Primary Key Elements
Element
Description
Default
generator-type Identifies the facility used to generate primary keys. Values include Oracle, SQLServer, or SQLServer2000, NamedSequenceTable.
generator-name Defines the Oracle SEQUENCE, or a the name of a SEQUENCE table used.
key-cache-size Specifies the size of the key cache.
create-default-dbms-tables Determines behavior related to if and how the EJB container will create database tables. Disabled