![]() ![]() ![]() ![]() ![]() ![]() |
The sections that follow describe WebLogic Server value-added features for programming and using entity beans in applications, and provide 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 Bean Features.
For a description of the overall bean development process, see Implementing Enterprise Java Beans.
WebLogic Server provides these features to improve performance and throughput for entity EJBs:
Figure 6-1 illustrates the lifecycle of an entity bean instance. The sections that follow describe pooling and how the container populates and manages the free pool and the cache.
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. In this release of WebLogic Server, administrators can also initialize pools on demand via the Administration Console. When a pool is initialized, it is reset to the state it was in immediately after the EJB was deployed. For information, see
Initialize the idle bean cache and pool of an EJB in Administration Console Online Help.
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.
You can configure WebLogic Server to remove entity beans that have remained in the pool unused for a period of time specified in idle-timeout-seconds
element in the pool
element. When beans have been in the pool unused for the amount of time you specify in idle-timeout-seconds
, they are removed from the pool until the number of beans in the pool reaches the number specified in initial-beans-in-free-pool
; the number of beans in the pool will never fall below the number specified in initial-beans-in-free-pool
.
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.
An ACTIVE instance is currently enlisted in a transaction. After completing the transaction, the instance becomes READY, and remains in cache until space is needed for other beans.
The Current Beans in Cache field in the Administration Console Monitoring tab displays the count of READY and ACTIVE beans. Additionally, in this release of WebLogic Server, Administrators can initialize caches on demand via the Administration Console. When a cache is initialized, it is reset to the state it was in immediately after the EJB was deployed. For information, see Initialize the idle bean cache and pool of an EJB in Administration Console Online Help.
The effect of the max-beans-in-cache element, and the quantity of instances with the same primary key allowed in the cache vary by concurrency strategy. Table 6-1 lists, for each concurrency strategy, how the value of the max-beans-in-cache element in weblogic-ejb-jar.xml
limits the number of entity bean instances in the cache, and how many entity bean instances with the same primary key are allowed in the 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.
You can configure WebLogic Server to periodically remove entity instances from cache when they have been idle—not participated in a transaction—for a period of time specified in idle-timeout-seconds
. For a dedicated cache, the fixed periodicity of the cleaning task is equal to the value of idle-timeout-seconds
. For an application level cache, multiple types of entity beans may share the cache each of which is allowed to have its own value of idle-timeout-seconds
. In this case, the fixed periodicity of the cleaning task is equal to MIN(Set of idle-timeout-seconds for all beans in cache)
, and the cleaning task may run with a variable periodicity.
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 beans that are involved in transactions can be passivated when necessary in order to attempt to prevent a CacheFullException when an attempt is made to insert an entity bean into a cache that is full. Passivation is handled automatically by the EJB container and you do not need to change the way you program EJBs in order to take advantage of this feature. However, you can optionally program your EJBs to communicate to the cache that they are done performing all operations in the current transaction. The cache can then make use of this information when evaluating beans for the possibility of passivation.
To optionally program EJBs to notify their cache that they are done performing operations in the current transaction, you can use the operationsComplete
Java API as follows:
weblogic.ejb.interfaces.EJBLocalObject
public.void.operationsComplete()
weblogic.ejb.EJBObject
public.void.operationsComplete()
This section describes how and when the persistent data for a CMP 2.1 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 the finders-load-bean element in the persistence element of weblogic-ejb-jar.xml.
ejbLoad()
—For CMP 2.1 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. That is, 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 not perform the 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.
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:
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 your 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.
According to the EJB specification, updates made by a transaction must be reflected in the results of query-finders and ejbSelect
s issued during the transaction. This requirement can slow performance. If you prefer not to flush the cache before the query is executed, you can change the value of the include-updates element in weblogic-cmp-jar.xml
from its default value of True
to False
.
The decision to disable cache flushing depends on whether performance is more important than seeing the most current data. Setting include-updates
to False
provides the best performance but updates of the current transaction are not reflected in the query. If include-updates
is True
the container flushes all changes for the transactions to the database before executing the new query.
You can safely turn cache flushing off if your transactions do not re-query modified data—a common scenario—and get the best performance.
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. There are no restrictions on the number of different entity beans that may reference an individual cache.
Application-level caching offers the following advantages:
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.
To configure an application-level cache:
weblogic-application.xml
file is located in the META-INF directory of the EAR file.entity-cache
element of weblogic-application.xml
. For a definition of this element and the child elements it contains, see
“entity-cache” in Developing Applications with WebLogic Server.weblogic-ejb-jar.xml
. weblogic-application.xml.
caching-strategy
specified in weblogic-application.xml
. A read-only entity can only use a Multiversion application-level cache. For more information, see
“caching-strategy” in Developing Applications with WebLogic Server.
The weblogic-application.xml
deployment descriptor is documented in the
“Application.xml Deployment Descriptor Elements” section of Developing Applications with WebLogic Server.
Every entity EJB must have a primary key that uniquely identifies an entity bean within its home. Each entity bean instance can 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.
You can map a primary key to one or multiple fields:
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.xm
l. 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.
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-field
s 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
.
If your entity EJB uses an anonymous primary key class, you must 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: |
Note: | 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). |
Follow these suggestions when using primary keys with WebLogic Server:
ejbCreate
. Instead, allow the container to create the primary key class internally, as described in Automatically Generating Primary Keys.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
method within the ejbCreate
method.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:
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
. In this case, the cmr-field
is initialized automatically, and the setXXX
method for the cmr-field
cannot be used. Conversely, if the cmp-field
is not a primary key field, the cmp-field
is read-only. The column is updated using the cmr-field
, and the cmp-field
provides a read-only view of the foreign key.WebLogic Server supports the 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:
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.Whichever method of generated primary keys you use, see the instructions in Declaring Primary Key Field Type.
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.
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.
When using the Oracle SEQUENCE
object for generating primary keys:
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.
SEQUENCE
schema object. If you migrate an application that uses synonyms for SEQUENCE
s from a release prior to WebLogic Server 8.1 to this release, the following errors result:
[EJB:011066]During EJB deployment, error(s) were encountered while setting up The ORACLE SEQUENCE named 'XXX' with INCREMENT value '1'
[EJB:011064]The ORACLE SEQUENCE named 'XXX' with INCREMENT '1' was not found in the database'
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>
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.
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:
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.
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.
In this release of WebLogic Server, by default, the EJB container trims string-valued CMP fields of their trailing spaces when they are retrieved from a database. All string-valued CMP fields are also trimmed of their trailing spaces in their set method.
Untrimmed primary key fields can cause comparison operators to fail and can result in non-portable behavior. Automatic string trimming is beneficial because it causes a string retrieved from a database to be identical to the string that was inserted into the database. For instance, suppose:
char(10)
datatype in databasesmith
" into the database columnsmith
" being inserted into the databaseSELECT
statement to retrieve "smith
" from the database, only, due to the database-appended characters, "smith
" is retrieved
A comparison of the retrieved "smith
" value with the original "smith
" string would fail unless the retrieved value was first trimmed of its trailing spaces. With this release of WebLogic Server, the trailing spaces are trimmed automatically and, therefore, the comparison would not fail.
Automatic string trimming is enabled by default in this release. When you use DDConverter to convert deployment descriptors from prior releases of WebLogic Server, DDConverter automatically disables string trimming in the new deployment descriptors it creates.
If you want to disable string trimming for deployment descriptors that are newly created in this release of WebLogic Server, you can set disable-string-trimming
in weblogic-cmp-jar.xml
to True
. For more information on the disable-string-trimming
element, see disable-string-trimming.
The following sections provide instructions for mapping entity EJBs to database tables and controlling database access behaviors.
A CMP bean can be mapped to one or more database tables. When a CMP bean is mapped to multiple tables, each table contains a row that corresponds to a particular bean instance. So, each table to which a bean maps will have the same number of rows at any point in time, and contain the same set of homogeneous primary key values. Consequently, each table must have the same number of primary key columns, and corresponding primary key columns in different tables must have the same type, though they may have different names. Tables that map to the same bean must not have referential integrity constraints declared between their primary keys. If they do, removal of a bean instance can result in a runtime error.
You map the cmp-fields of a bean to the columns of a table using the table-map element in weblogic-cmp-jar.xml
, specifying one table-map
element for each database table to which the bean maps. Each table-map
element maps the primary key column(s) of the table to the primary key field(s) of the bean. Non-primary key fields may only be mapped to a single table.
Listing 6-1 and Listing 6-2 contain table-map
elements for a bean that maps to a single and a bean that maps to multiple tables, respectively.
<table-map>
<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>
<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>
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. 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. |
Enable this feature using the create-default-dbms-table
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.
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.
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:
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-field
s 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
.
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
.
Note: | In a one-to-one relationship, if the parent bean’s primary key is embedded in the child bean's CMR field, when the EJB container creates the beans, it will not check if the parent bean has children, for performance reasons. To avoid a duplicationKeyException database exception, you must set the foreign key constraint on the child table in the database. |
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.
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 "True
".
If you choose to delay database updates for a transaction that updates related beans, you must 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.
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 or when a transaction is rolled back. This behavior is referred to as long-term caching. You enable long-term caching by setting the cache-between-transactions
element in weblogic-ejb-jar.xml
to true
.
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. This would make caching between transactions impossible. |
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. |
Table 6-3 lists the allowable values for the cache-between-transactions
element by entity bean type and concurrency strategy.
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. |
Dynamic queries allow you to construct and execute EJB-QL or SQL queries programmatically in your application code.
Using dynamic queries provides the following benefits:
enable-dynamic-queries
element in the EJB’s weblogic-ejb-jar.xml
to True
:
<enable-dynamic-queries>True</enable-dynamic-queries>
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 execute 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.
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);
WebLogic Server supports Oracle and DB2 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.
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>Blob</dbms-column-type>
<dbms-default-value>DB2</dbms-default-value>
</field-map>
In this release of WebLogic Server, cmp-fields of type byte[] mapped to a Blob are not serialized by default; the EJB container persists the byte[] directly and does not serialize it.
To cause WebLogic Server to serialize cmp-fields of type byte[] mapped to a Blob in an Oracle database, set the serialize-byte-array-to-oracle-blob compatibility flag, which was introduced in WebLogic Server 8.1 SP02, to True
.
The following XML code shows how to specify a CLOB object using the dbms-column element in weblogic-cmp-jar-xml
.
<field-map>
<dbms-default-value>Oracle</dbms-default-value>
<cmp-field>description</cmp-field>
<dbms-column>product_description</dbms-column>
<dbms_column-type>Clob</dbms-column-type></field-map>
The Oracle 9i and 10g drivers have different requirements for successful insertion of CLOB column values into database rows. The Oracle 9i driver requires that a database row is locked before a CLOB value can be inserted into it. As a result, on Oracle 9i, WebLogic Server does the following to insert a row that contains a CLOB column value into a table:
While these steps are necessary for successful insertion of a row that contains a CLOB column value on Oracle 9i, the steps cause an unnecessary performance hit on Oracle 10g. The Oracle 10g driver features improved handling of CLOBS and does not require a lock on a row before a CLOB column value can be inserted into it. On Oracle 10g, WebLogic Server uses a single INSERT
statement to insert a row with a CLOB column value into a table, which results in increased performance of CMP EJBs.
To make use of this WebLogic Server optimization for Oracle 10g, you do not need to configure anything additional. Simply specify Oracle as your database and WebLogic Server checks to see if your Oracle version is Oracle 9i or Oracle 10g. If WebLogic Server identifies your database as Oracle 10g, rows containing CLOB values are inserted into tables in single INSERT
statements. If WebLogic Server identifies your database as Oracle 9i, rows containing CLOB values are inserted into tables in three steps as previously described.
For more information, see Handling CLOBs - Made easy with Oracle JDBC 10g and Oracle product documentation.
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.
You specify field groups in the field-group element of weblogic-cmp-jar.xml
file, as shown in Listing 6-3.
<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 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
.
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:
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:
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, you must 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.
When using batch operations, you must 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:
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. weblogic-ejb-jar.xml
file. weblogic-cmp-jar.xml
to either Blob
or Clob
, batch operation automatically turns off because you will not save much time if a Blob or Clob column exists in the database table. In this case, WebLogic Server performs one insert per bean, which is the default behavior. You can choose to cache read-only entity EJBs at the query level. Caching read-only entity EJBs at the query level improves performance because it enables the EJBs to be accessed in cache by any finder, thereby avoiding the need to access the database. For information, see enable-query-caching.
In this release of WebLogic Server, you can use EJB-QL or standard or database-specific SQL for entity beans that use container-managed persistence (CMP). BEA recommends that you use EJB-QL (with or without WebLogic extensions) for most queries and use SQL only when needed (for instance, to make use of vendor-specific features that cannot be accessed without using vendor-specific SQL).
You can use SQL in queries that cache multiple related objects, to implement finder and select methods, or with stored procedures.
To use EJB-QL in queries in this release of WebLogic Server, you do not need to change any mapping information in weblogic-cmp-jar.xml
. You simply continue to map each CMP and CMR field to database columns as you did in pre-9.0 releases of WebLogic Server. For information, see, Configuring Entity EJBs for Database Operations and Using Container-Managed Relationships (CMRs). To use SQL in queries, you must describe the shape of the SQL result with the sql-shape element. SQL shape primarily consists of the SQL tables and columns that are returned. The EJB containers uses the SQL shape together with the CMP and CMP field mappings to return objects from the query. For more information, see:
Container-managed relationships (CMRs) are relationships that you define between two entity EJBs, analogous to the relationships between the tables in a database. If you define a CMR between two EJBs that are involved in the same processing task, your application can benefit from these features:
The sections that follow describe the features and limitations of WebLogic Server CMRs. For instruction on configuring CMRs, see Defining Container-Managed Relationships (CMRs).
You can define a relationship between two WebLogic Server entity beans that will be packaged in the same JAR and 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. The abstract schema for each bean that participates in a container-managed relationship must be defined in the same ejb-jar.xml
file.
Note: | EJB 2.1 states that if an entity bean does not have a local interface, the only CMR in which it can participate is a unidirectional one, from itself to another entity bean. |
Note: | However, WebLogic Server allows an entity bean with only a remote interface to: |
Note: | Because this feature is not specified in EJB 2.1, entity beans that have only remote interfaces, and either participate in bidirectional relationships or are the target of a unidirectional relationship, may not be portable to other application servers. |
An entity bean can have a one-to-one, one-to-many, or many-to-many relationship with another entity bean.
Any CMR, whether one-to-one, one-to-many, or many-to-many, can be either unidirectional or bidirectional. The direction of a CMR determines whether the bean on one side of the relationship can be accessed by the bean on the other side.
Unidirectional CMRs can be navigated in one direction only—the “dependent bean” is unaware of the other bean in the relationship. CMR-related features such as cascade deletes can only be applied to the dependent bean. For example, if cascade deletes have been configured for a unidirectional CMR from to EJB1
to EJB2,
deleting EJB1
will cause deletion of EJB2
, but deleting EJB2
will not cause deletion of EJB1
.
Note: | For the cascade delete feature, the cardinality of the relationship is a factor—cascade deletes are not supported from the many side of a relationship, even if the relationship is bidirectional. |
Bidirectional relationships can be navigated in both directions—each bean in the relationship is aware of the other. CMR-related features are supported in both directions. For example, if cascade deletes have been configured for a bidirectional CMR between EJB1
to EJB2,
deleting either bean in the CMR will cause deletion of the other bean.
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.
Defining a CMR involves specifying the relationship and its cardinality and direction in ejb-jar.xml
. You define database mapping details for the relationship and enable relationship caching in weblogic-cmp-jar.xml
. These sections provide instructions:
Container-managed relationships are defined in the ejb-relation
element of ejb-jar.xml.
Listing 6-4 shows the ejb-relation
element for a relationship between two entity EJBs: TeacherEJB
and StudentEJB
.
The ejb-relation
element contains a ejb-relationship-role
for each side of the relationship. The role elements specify each bean’s view of the relationship.
<ejb-relation>
<ejb-relation-name>TeacherEJB-StudentEJB</ejb-relation-name>
<ejb-relationship-role>
<ejb-relationship-role-name>teacher-has-student
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>TeacherEJB</ejb-name>
</relationship-role-source>
<cmr-field>
<cmr-field-name>teacher</cmr-field-name>
</cmr-field>
</ejb-relationship-role>
<ejb-relationship-role>
<ejb-relationship-role-name>student-has-teacher
</ejb-relationship-role-name>
<multiplicity>Many</multiplicity>
<relationship-role-source>
<ejb-name>StudentEJB</ejb-name>
</relationship-role-source>
<cmr-field>
<cmr-field-name>student</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
<cmr-field>
</ejb-relationship-role>
The cardinality on each side of a relationship is indicated using the multiplicity
element in its ejb-relationship-role
element.
In Listing 6-5, the cardinality of the TeacherEJB-StudentEJB
relationship is one-to-many—it is specified by setting multiplicity
to one
on the TeacherEJB
side and Many
on the StudentEJB
side.
The cardinality of the CMR in Listing 6-5, is one-to-one—the multiplicity
is set to one
in both role elements for the relationship.
<ejb-relation>
<ejb-relation-name>MentorEJB-StudentEJB</ejb-relation-name>
<ejb-relationship-role>
<ejb-relationship-role-name>mentor-has-student
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>MentorEJB</ejb-name>
</relationship-role-source>
<cmr-field>
<cmr-field-name>mentorID</cmr-field-name>
</cmr-field>
</ejb-relationship-role>
<ejb-relationship-role>
<ejb-relationship-role-name>student-has-mentor
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>StudentEJB</ejb-name>
</relationship-role-source>
</ejb-relationship-role>
If a side of a relationship has a <multiplicity>
of Many,
its <cmr-field>
is a collection, and you must specify its <cmr-field-type>
as java.util.Collection
, as shown in the StudentEJB
side of the relationship in Listing 6-4. It is not necessary to specify the cmr-field-type
when the cmr-field
is a single valued object.
Table 6-4 lists the contents of cmr-field
for each bean in a relationship, based on the cardinality of the relationship.
The directionality of a CMR is configured by the inclusion (or exclusion) of a cmr-field
in the ejb-relationship-role
element for each side of the relationship
A bidirectional CMR has a cmr-field
element in the ejb-relationship-role
element for both sides of the relationship, as shown in Figure 6-4.
A unidirectional relationship has a cmr-field
in only one of the role elements for the relationship. The ejb-relationship-role
for the starting EJB contains a cmr-field
, but the role element for the target bean does not. Figure 6-5 specifies a unidirectional relationship from MentorEJB
to StudentEJB
— there is no cmr-field
element in the ejb-relationship-role
element for StudentEJB
.
Each CMR defined in ejb-jar.xml
must also be defined in a weblogic-rdbms-relation element in weblogic-cmp-jar.xml
. weblogic-rdbms-relation
identifies the relationship, and contains the relationship-role-map element, which maps the database-level relationship between the participants in the relationship, for one or both sides of the relationship.
The relation-name in weblogic-rdbms-relation
must be the same as the ejb-relation-name
for the CMR in ejb-jar.xml
.
For one-to-one and one-to-many relationships, relationship-role-map is defined for only one side of the relationship.
For one-to-one relationships, the mapping is from a foreign key in one bean to the primary key of the other.
Figure 6-6 is the weblogic-rdbms-relation
element for a the one-to-one relationship between MentorEJB
and StudentEJB
, whose <ejb-relation>
is shown in Figure 6-5.
<weblogic-rdbms-relation>
<relationship-role-map>
<relation-name>MentorEJB-StudentEJB</relation-name>
<weblogic-relationship-role>
<relationship-role-name>
mentor-has-student
</relationship-role-name>
<column-map>
</relationship-role-map>
<foreign-key-column>student</foreign-key-column>
<key-column>StudentID/key-column>
</column-map>
</weblogic-relationship-role>
For one-to-many relationships, the mapping is also always from a foreign key in one bean to the primary key of another. In a one-to-many relationship, the foreign key is always associated with the bean that is on the many side of the relationship.
Listing 6-7 is the weblogic-rdbms-relation
element for a the one-to-many relationship between TeacherEJB
and StudentEJB
, whose <ejb-relation>
is shown in Figure 6-4.
<weblogic-rdbms-relation>
<relationship-role-map>
<relation-name>TeacherEJB-StudentEJB</relation-name>
<weblogic-relationship-role>
<relationship-role-name>
teacher-has-student
</relationship-role-name>
<column-map>
</relationship-role-map>
<foreign-key-column>student</foreign-key-column>
<key-column>StudentID/key-column>
</column-map>
</weblogic-relationship-role>
For many-to-many relationships, specify a weblogic-relationship-role element for each side of the relationship. 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 relationship. The direction of a relationship does not affect how you specify the database mapping for the relationship.
Listing 6-8 shows the weblogic-rdbms-relation element for the friends relationship between two employees.
The FRIENDS
join table has two columns, first-friend-id
and second-friend-id
. Each column contains a foreign key that designates a particular employee who is a friend of another employee. The primary key column of the employee table is id
. The example assumes that the employee bean is mapped to a single table. If employee bean is mapped to multiple tables, then the table containing the primary key column must be specified in the relation-role-map.
For an example, see Specifying CMRs for EJBs that Map to Multiple Tables.
<weblogic-rdbms-relation>
<relation-name>friends</relation-name>
<table-name>FRIENDS</table-name>
<weblogic-relationship-role>
<relationship-role-name>first-friend
</relationship-role-name>
<relationship-role-map>
<column-map>
<foreign-key-column>first-friend-id</foreign-key-column>
<key-column>id</key-column>
</column-map
</relationship-role-map>
<weblogic-relationship-role>
<weblogic-relationship-role>
<relationship-role-name>second-friend</relationship-role-
name>
<relationship-role-map>
<column-map>
<foreign-key-column>second-friend-id</foreign-key-column>
<key-column>id</key-column>
</column-map>
</relationship-role-map>
</weblogic-relationship-role>
</weblogic-rdbms-relation>
A CMP bean that is involved in a relationship may be mapped to multiple DBMS tables.
If neither of the beans in a relationship is mapped to multiple tables, then the foreign-key-table
and primary-key-table
elements may be omitted since the tables being used are implicit.
Listing 6-9
contains a relationship-role-map for a CMR in which the bean on the foreign-key side of a one-to-one relationship, Fk_Bean
, is mapped to two tables: Fk_BeanTable_1
and Fk_BeanTable_2
.
The foreign key columns for the relationship, Fk_column_1
and Fk_column_2
, are located in Fk_BeanTable_2
. The bean on the primary key side, Pk_Bean
, is mapped to a single table with primary-key columns Pk_table_pkColumn_1
and Pk_table_pkColumn_2
.
The table that contains the foreign-key columns is specified by the <foreign-key-table>
element.
<relationship-role-map
<foreign-key-table>Fk_BeanTable_2</foreign-key-table>
<column-map>
<foreign-key-column>Fk_column_1</foreign-key-column>
<key-column>Pk_table_pkColumn_1</key-column>
</column-map>
<column-map>
<foreign-key-column>Fk_column_2</foreign-key-column>
<key-column>Pk_table_pkColumn_2</key-column>
</column-map>
</relationship-role-map>
CMR fields are not stored as attributes of an implementation class—they are accessible in the bean through CMR field accessor methods that you write. CMR field accessor methods:
To allow remote clients to use CMR field accessor methods, put the getter and/or setter method signatures in the remote interface. However, CMR fields of a Collection datatype cannot be exposed in the remote interface. A CMR field that is a Collection can only be accessed by local methods.
When a cascade delete is performed, the deletion of a bean instance that participates in a relationship with another bean instance 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:
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 . |
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.
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 is 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:
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, an 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 accountBean
and addressBean
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, it is a good idea to let the finder method know via the relationship caching feature.
Note: | The relationship caching feature has the following limitations: |
Note: | 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. |
With relationship caching enabled, changes to the relationship are automatically reflected in cache. For instance, if an instance is added on the “many” side of a one-to-many relationship, that change is reflected in the cached relationship—a subsequent query to the bean on the “one” side of the relationship causes the relationship to be refreshed in cache, so that the new instance is available to the query.
To enable relationship caching:
weblogic-cmp-jar.xml
file.
If a caching-name
element is specified in the weblogic-query
element, 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.
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
.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
elements 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
element 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-element
s that you can specify. However, setting too many caching-element
levels could have an impact on the performance of the current transaction.
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.
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.
With 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.
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 as 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. |
To prevent optimistic data from going stale, the container activates a new bean instance for each transaction so that requests proceed in parallel. WebLogic Server calls ejbLoad()
for entity beans based on the value specified in read-timeout-seconds, provided the value of cache-between-transactions
is True
.
You can invalidate optimistic beans explicitly when the underlying data is updated outside the EJB container (this is also known as a "backdoor update"). For information, see Invalidating Entity EJBs Explicitly
By default, when a bean that has a concurrency-strategy
of Optimistic
is deployed in a cluster and a member of the cluster updates the bean, the EJB container attempts to invalidate all copies of the bean in all servers in the cluster. This invalidation allows you to avoid optimistic concurrency failures, but can be a drain on performance because it is a resource-intensive operation. If you prefer, you can set cluster-invalidation-disabled in weblogic-cmp-jar.xml to True
to prevent the EJB container from attempting to invalidate copies of the bean across the cluster.
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: | 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-map element for the bean in weblogic-cmp-jar.xml
file.
The verify-rows element specifies the rows in a table that the EJB container should check when optimistic concurrency is used; the verify-columns element specifies how columns in a table are checked for validity when you use the optimistic concurrency strategy.
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. Checking all rows entails additional overhead because 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.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.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.Note: | If verify-rows is set to Read then the verify-columns element cannot have a value of Modified since this combination would result in only checking the modified rows. |
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 or any positive integer, and must increment by 1 whenever the row is modified. For more information, see version-column-initial-value.
Additionally, if you use database triggers to update version columns in the database and you set trigger-updates-optimistic-column to True
, the database triggers must initialize the version column in the database when the bean is created.
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.
By default, the EJB container manages the version and timestamp columns and ensures that these columns are kept up to date. If you choose to instead let database triggers maintain version and timestamp columns, set the value of trigger-updates-optimistic-column to True
.
Note: | The version or timestamp column is not updated if the transaction did not modify any 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. |
verify-columns
is set to Version
or Timestamp
: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
.
weblogic-cmp-jar.xml
file.If the EJB is mapped to multiple tables, optimistic checking is only performed on the tables that are updated during the transaction.
For Oracle databases, if you set verify-columns
to Modified
for an entity EJB with a CMP non-key field type java.util.Date
and implementation type Oracle DATE
, WebLogic Server throws an optimistic concurrency violation exception when a simple update is made to the non-key DATE
field—even though only one user is updating the record.
This problem occurs because of a mismatch in date value precision between the Oracle DATE
column and the java.util.Date
type. The java.util.Date
type is in milliseconds, and the Oracle DATE
column is not. There are two ways to avoid this error:
Timestamp
, a higher precision type introduced in Oracle9i.java.util.Date
value. To accomplish this, prepare a date field for an entity bean java.util.Date
field in this way:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MILLISECOND, 0); // clears millisecond
Date myDate = cal.getTime();
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.
To allow generation of more efficient code for read-only beans, create and remove operations are not allowed for EJBs that use ReadOnly concurrency in this release of WebLogic Server.
To allow read-only beans to use create and remove operations—for instance, to support legacy behavior—set the allow-readonly-create-and-remove element in weblogic-cmp-jar.xm
l to True
.
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-5.
Mitigate deadlock risk by setting use-select-for-update in
weblogic-cmp-jar. . 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.
|
If the database concurrency control is sufficient for your application and you do not require additional features provided by the container.
|
||||
Specify the concurrency mechanism for a bean by setting the concurrency-strategy
element in the entity-cache element 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.
If you do not specify a concurrency-strategy
, WebLogic Server uses Database
concurrency by default.
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.
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. You 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
) element 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 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 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 the read-write EJB enjoy true transactional behavior—the read-write
EJB’s cached state always matches the persistent data in the database.
These practices will reduce the likelihood of data consistency problems with the read-mostly pattern.
read-timeout-seconds
element in weblogic-ejb-jar.xml
:ejbStore().
read-timeout-seconds
setting for its read-only counterparts. If you are running EJB 2.x, you can approximate the read-mostly pattern using a single bean that uses optimistic concurrency. An optimistic bean acts like a read-only bean 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.
The invalidation-target element in the entity-descriptor
element 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.x CMP entity bean. The target ejb-name must be a read-only entity EJB.
In this release of WebLogic Server, you can invalidate any optimistic entity bean that has cache-between-transactions
enabled, by calling the following invalidate()
method on either the CachingHome
or CachingLocalHome
interface.
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 code shows how to cast the home to CachingHome
and then 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 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 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 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.
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 type of feature or behavior. The table in each section defines relevant elements terms of: the behavior it controls, the parent element 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
.
|
|||
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 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 an example, see Defining a Many-to-Many Relationship.
|
|||
![]() ![]() ![]() |