All Examples All EJB Examples
These examples are two packages that demonstrate an Enterprise JavaBean. Please run these examples before attempting to create your own Enterprise JavaBeans, as they will show you the different steps involved. You should also have run our basic examples to gain an introduction to EJBeans.
The example is an entity EJBean called AccountBean that demonstrates using a WebLogic extension to EJB called isModified. The extension supplies the name of a method that's to be called and checked every time the bean is to be stored. Providing a method and setting it as appropriate will improve performance by eliminating unnecessary writing of the bean to the database.
The "unnecessary writing" comes about because normally the container -- when you're using container-managed persistence -- must write the contents of the bean after every invocation, as the container has no way of knowing that the bean's contents haven't been modified by the invocation. This WebLogic extension provides a mechanisim for telling the container when the bean has (and hasn't) been changed.
This optimization works by taking advantage of what we know about the logic of our business methods to reduce the number of times we go to the database to save the beans.
If your bean is such that there are no methods that don't change the value of the bean, and thus the container should save the contents after each invocation, then this technique is not appropriate. There are other circumstances (such as a shared databases) where you should not use this technique.
The example demonstrates:
Using this feature will not remove your EJBeans' portability, as you are simply adding two methods and a transient value that other containers will ignore.
This is an advanced usage of Enterprise JavaBeans, and it's easy to make a mistake with it. It should only be used by developers who have an in-depth understanding of EJB and databases.
isModifiedMethodName isModified
public boolean isModified()
We do this by setting the dirty flag:
setModified(true); // to force saving by the containeror
setModified(false); // to stop saving by the containerIn the container-managed example, flag is set by these methods:
Method | Sets flag |
deposit(double amount) | setModified(true) |
withdraw(double amount) | setModified(true) |
ejbLoad() | setModified(false) |
ejbStore() | setModified(false) |
Notice that the balance() method does not set the flag, as it's a method that does not change the value of the bean. Only methods that modify the value of the bean need to set the flag to true; methods that restore the value of the bean from the database need to reset the flag to false.
Reults showing how this works in practice for both the client and the server when running the container-managed example are shown in the section Run the examples.
Instead, it calls ejbLoad() and ejbStore() at the beginning and end of every transaction, which in turn can call isModified() to determine if the bean doesn't need to interact with a database because it knows it is in sync. The bean must set the dirty flag to true in any place where the state changes.
When ejbActivate() is called, we are associating an instance of the EJBean with a logical primary key. The contents, however, are not in sync with the database. Either they have never been set -- because you have a new instance -- or they are an old value because you have an instance from the free pool. As this is bean-managed persistence, we need to tell the container to sync those contents to the database.
What should now be clear is that methods such as ejbActivate(), ejbPassivate(), and ejbRemove() must set the dirty flag to true, because the bean could be pooled and reused.
With bean-managed persistence, we need to sync the contents to the database whenever an operation has potentially changed them. We do this by setting the dirty flag:
setModified(true); // to force saving in ejbStoreWhen ejbStore() is subsequently called, this flag setting will be used to force a write and update the database.
In the bean-managed example, the flag is set by these methods:
Method | Sets flag |
ejbActivate() | setModified(true) |
ejbPassivate() | setModified(true) |
setEntityContext() | setModified(true) |
deposit(double amount) | setModified(true) |
withdraw(double amount) | setModified(true) |
ejbRemove() | setModified(true) |
refresh(AccountPK pk) | setModified(false) |
ejbLoad() | setModified(false) |
ejbStore() | setModified(false) |
ejbPostCreate(String accountId, double initialBalance) | setModified(false) |
As you'll use a database for the persistent storage of the entity EJBean, you'll need to set it up. Note that the persistent storage is completly invisible to the client; the actual storage is either handled by the container (container-managed) or by the EJBean directly (bean-managed).
This example is shipped "pre-built"; you can either run it as shipped, or build the example and run it to test that you are able to successfully build and run EJBeans.
These three sections cover what to do:
We provide separate build scripts for Windows NT and UNIX:
The "build" scripts build individual examples, such as these entries for Windows:
$ build extensions isModified
$ build extensions isModifiedBeanManagedTo build under Microsoft's JDK for Java, use
$ build extensions isModified -msThese scripts will build the example and place the files in the correct locations:
Note: You'll need to first build the containerManaged example, as these examples depend on classes from that example.
With database persistence, each instance of an EJBean is written to a row in a table. The table (ejbAccounts) must be created and exist in the database before the example is run. If you are using the evaluation copy of Cloudscape that is included with WebLogic, this table has already been created in the "demo" database.
You'll need to:
"create table ejbAccounts (id varchar(15), bal float, type varchar(15))"
# You can use this connection pool with any of the EJBean examples. # Uncomment to use: weblogic.jdbc.connectionPool.demoPool=\ url=jdbc:cloudscape:demo,\ driver=COM.cloudscape.core.JDBCDriver,\ initialCapacity=1,\ maxCapacity=2,\ capacityIncrement=1,\ props=user=none;password=none;server=noneYou can use this pool for Cloudscape. For other databases, you'll need to set an appropriate url and driver, such as
url=jdbc:weblogic:oracle,\ driver=weblogic.jdbc.oci.Driver,\
# Add an ACL for the connection pool: weblogic.allow.reserve.weblogic.jdbc.connectionPool.demoPool=everyone
If you need more information about how to use connection pools, read Using WebLogic JDBC: Using connection pools.
We provide a commented-out version in the property that begins with "weblogic.ejb.deploy" that you can use. You'll need to adjust the property depending on which EJBeans you're building and are deploying, or if the location of the files differs from the installed location.
Note: If you're running under the Microsoft SDK for Java, you'll also need to add the path to the .jar to the CLASSPATH for your WebLogic Server.
If you're starting the Server from the command line, you'll need to add an entry such as c:/weblogic/eval/cloudscape/lib/cloudscape.jar to the Java system classpath before starting the server, as described in the Administrators Guide Setting up and starting the WebLogic Server.
You can check that the EJBean has been deployed correctly either by checking the server command line window, or by opening the Console and examining "EJB" under the "Distributed objects"; you should see isModified.AccountHome and isModifiedBeanManaged.AccountHome deployed, and can monitor their activity.
$ java examples.ejb.extensions.isModified.Clientor
$ java examples.ejb.extensions.isModifiedBeanManaged.Client
If you're not running the WebLogic Server with its default settings, you will have to run the client using:
$ java examples.ejb.extensions.isModified.Client "t3://WebLogicURL:Port"or
$ java examples.ejb.extensions.isModifiedBeanManaged.Client "t3://WebLogicURL:Port"
where:
Parameters are optional, but if any are supplied, they are interpreted in this order:
Beginning isModified.Client... Part A: using isModified... Looking up account 10020... Did not find 10020 Account 10020 being created; opening balance is $3000.0 Depositing $100.0 Current balance is $3100.0 Withdrawing $100.0 Current balance is $3000.0 Part B: not using isModified... Contacting the home... Finding the account... Looking up account 10020... Account 10020 found; balance is $3000.0 Depositing $100.0 Current balance is $3100.0 Withdrawing $100.0 Current balance is $3000.0 End isModified.Client...However, the interesting part is over on the server. Here, you'll see results similar to this:
ejbActivate(): 1966429, PK = 10020; isDirty = false ejbLoad(): 1966429, PK = 10020; isDirty = false setModified(): 1966429, PK = 10020; isDirty = false: saving not required balance(): balance $3300.0 isModified(): isDirty = false deposit(): Depositing $100.0 into '10020' setModified(): 1966429, PK = 10020; isDirty = true: requires saving isModified(): isDirty = true ejbStore(): 1966429, PK = 10020; isDirty = true setModified(): 1966429, PK = 10020; isDirty = false: saving not required balance(): balance $3400.0 isModified(): isDirty = false withdraw(): Withdrawing $100.0 from '10020' setModified(): 1966429, PK = 10020; isDirty = true: requires saving isModified(): isDirty = true ejbStore(): 1966429, PK = 10020; isDirty = true setModified(): 1966429, PK = 10020; isDirty = false: saving not required balance(): balance $3300.0 isModified(): isDirty = false ejbActivate (1946332, PK = 10020) ejbLoad: (1946332, PK = 10020) balance (1946332, PK = 10020) ejbStore (1946332, PK = 10020) Depositing $100.0 into '10020' ejbStore (1946332, PK = 10020) balance (1946332, PK = 10020) ejbStore (1946332, PK = 10020) Withdrawing $100.0 from '10020' ejbStore (1946332, PK = 10020) balance (1946332, PK = 10020) ejbStore (1946332, PK = 10020) ejbPassivate (1946332, PK = 10020) ejbPassivate(): 1966429, PK = 10020; isDirty = false
Colored red are calls to the server using the bean with isModified. Notice how after a call to balance() (shown in bold), no further database activity takes place, as the bean is telling the container it knows it is in sync. In this part, three calls are made to the database.
Colored navy are calls to the server using the bean without isModified. Notice how after a call to balance() (shown in bold), there's a call to ejbStore() and database activity takes place, as the container has no way of knowing that the call didn't modify any of the bean's values (it was a simple "get") and so must write the bean to the persistent store. In this part, six calls are made to the database -- twice the number of the previous part.
Similar results will be seen if you run the bean-managed client.
Copyright © 1997-1999 BEA Systems, Inc. All rights reserved.
Last updated 09/06/1999