Over the last several years, developers have increasingly made the leap to standards-based, multi-tier application development. The majority of companies making this move are standardizing on the Java™ 2 Platform, Enterprise Edition (J2EE) so their developers can leverage facilities like:
These J2EE technologies and API's provide the enabling ingredients to build enterprise applications that deploy to any J2EE-compliant application server and use any SQL-compliant relational database. However, as any seasoned J2EE developer will tell you, there is a major difference in effort between creating a J2EE-compliant application, and delivering one that is modular, performant, and scalable.
This paper explains how Oracle's J2EE-compliant Business Components for Java (BC4J) framework considerably simplifies delivering solutions that exploit the full set of J2EE technologies above by providing an off-the-shelf implementation of the numerous additional design patterns you would normally have to code by hand to achieve this goal. In fact, many of Oracle's own applications development teams count on BC4J to deliver highly functional, well-performing J2EE applications in record time. A growing number of internal and external teams leverage BC4J for their J2EE development because as we'll see below, the amount of "application plumbing" code required for the typical J2EE application is a lot more than first meets the eye. Since Oracle has made a substantial and long-term investment in the J2EE platform, the BC4J framework and the Oracle9i JDeveloper development environment are key parts of Oracle's current and future Java strategy to improve productivity for developers targeting the J2EE platform.
Since March of 1998 when EJB 1.0 first came on the scene, developers have learned a lot from their initial attempts to put J2EE technology into practice in real-world applications. These pioneers fed their experience back into the EJB development community as a set of best-practice coding techniques called the "J2EE Design Patterns". Many are listed and briefly described at Sun's J2EE Design Patterns web site. These guidelines begin where many EJB tutorials end, suggesting when and when not to apply what you've learned in the tutorials to achieve optimal results. In order to avoid the painful performance pitfalls that await the uninitiated, you and your team must study, understand, and apply these design patterns as you develop your own J2EE applications.
Fortunately, many of the techniques you need to learn are outlined in books like:
as well as in similar works by other authors. In addition to reading a good book or two on the subject, you can study the source code of Sun's Java Pet Store Demo for additional inspiration by observing how their developers put the design patterns into practice in this sample application.
Regardless of the kind of J2EE application your team is being asked to deliver, in the Pet Store Demo you'll find example code illustrating most of the common tasks all real-world applications have to perform, like:
In fact, a careful inventory of the Pet Store Demo source code reveals example implementations of many of the J2EE Design Patterns, like the:
Data Access Objects Pattern
which avoids unnecessary marshalling overhead by implementing dependent objects as lightweight, persistent classes instead of each as an Enterprise Bean,
Model/View/Controller (MVC) Pattern
where an "application object" exposes the data model of the application in a way that is cleanly separated from the layout code that presents the data,
Session Façade Pattern
which avoids inefficient remote client access of Entity Beans by wrapping them with a Session Bean,
Value Object Pattern
which avoids unnecessary network round-trips by creating one-off transport objects to group together a set of related attributes needed by a client program,
Page-by-Page Iterator Pattern
which avoids sending unnecessary data to the client by breaking a large collection into chunks for display, and the
Fast-Lane Reader Pattern
which avoids unnecessary overhead for read-only data by accessing JDBC API's directly.
As design patterns, these guidelines don't impose a particular implementation approach. There are many valid ways, ranging from simple, hand-coded solutions to ones leveraging more sophisticated, generic frameworks. Typically the difference between the approaches lies in the amount of work required of the individual developer. Understandably, as an example application built for learning purposes, the Pet Store Demo illustrates one possible approach to implementing the patterns in the context of a simple Web storefront application.
Of course, reading books and studying sample code can only take your team a small part of the way to the goal line. When the time comes to begin writing your own J2EE applications, there are two basic approaches you can use to put the J2EE Design Patterns into practice:
Implement the design patterns manually...
writing and debugging the code for each occurrence of each pattern code by hand, or
Apply a framework of helper-objects...
that implement the design patterns for you in a generic way.
After examining the 200+ classes that comprise the fairly straightforward Java Pet Store application, it's easy to appreciate that implementing all of these best-practices design patterns entails writing a substantial amount of application plumbing code. Smart teams seek to minimize the amount of time spent writing and debugging this kind of code, preferring instead to dedicate their time to writing great business logic and user interfaces that differentiate their business from their competitors'. The framework-based approach described above is in line with Sun's own recommendations from their J2EE Blueprints book:
"Large scale development of object-oriented software requires frameworks. It is important to have a framework, so that every time the design requires two objects to interact, a developer does not have to come up with a whole new notion of how the interaction works out.” (J2EE Blueprints, Section 10.2.2.2)
A framework-based approach offers obvious productivity advantages, and scales better as the number of developers on the team begins to grow. Rather than teaching each developer how to hand-code all the patterns, each is trained instead in how to apply the framework objects to implement the solution. The typical decision you and your team have to make is whether to buy an off-the-shelf framework or build one yourselves.
Inevitably, teams that don't use an off-the-shelf offering end up gradually building their own team-specific framework over time as they realize more and more opportunities to generalize coding patterns into helper classes. This piecewise approach to cobbling together a team-specific framework has some downsides, however. It sacrifices the cohesiveness that is possible when the overall design of the framework is architected from the outset to provide a well-known set of collaborations like the J2EE design patterns require. Furthermore, building a framework yourself typically means dedicating and motivating a portion of your development resources to work full-time on generic application plumbing code to benefit the rest of the team. In practice, many teams that begin down this "roll your own" path quickly realize that the job requires a heroic effort and is a huge time sink, even with the best intentions and brightest staff.
Since designing, authoring, debugging, documenting, delivering, and maintaining a J2EE design patterns framework takes a significant amount of time and effort, more and more teams are leveraging off-the-shelf J2EE frameworks like Oracle's Business Components for Java (BC4J) that implement the patterns for them so they don't have to. This approach gives them a decisive leg-up in getting their J2EE applications built, deployed, and enhanced more quickly.
However, if you have never used a framework-based approach to implementing the J2EE Design Patterns, it may not immediately be clear what type of development effort a framework can save you. To get a better feel for the coding effort the design patterns require, let's dissect a simple example from the Java Pet Store Demo and then illustrate how the same example would be implemented using a J2EE framework like BC4J.
In the Pet Store Demo, a group of JSP pages provides the user
interface allowing a user to carry out the task of browsing the store catalog.
The product.jsp page is a typical example of one page in
this group. Since it displays master/detail business information, it is similar
to many pages in your own web applications. The Pet Store demo examples in this
whitepaper correspond to the 1.1.2 version of the demo.
After including the standard Pet Store banner at the top, the page displays the name of a product, like "Chihuahua", then lists the detail items for sale in the store corresponding to that product type. This results in a page whose dynamic content looks like what's shown in Figure 1.

A simplified version of the product.jsp that
produces these results is shown in Example 2. To clarify that the
tag libraries in use here are not a built-in part of the
J2EE platform, we've changed the j2ee prefix used in the
demo pages to use the more meaningful petdemo prefix
instead.
<%-- Product.jsp: Lists all items in the inventory for a particular product type. --%>Example 2: Source code for a simplified version of the Pet Store Demo's Product.jsp page
<%-- Note! Renamed "j2ee" tag library prefix to "petdemo" for clarity --%>
<%@ taglib uri="/technology/WEB-INF/tlds/taglib.tld" prefix="petdemo" %>
<%@ page import="com.sun.j2ee.blueprints.shoppingcart.catalog.model.Product" %>
<jsp:useBean id="catalog" scope="application"
class="com.sun.j2ee.blueprints.petstore.control.web.CatalogWebImpl"/>
<%
Product product = catalog.getProduct(request.getParameter("product_id"));
%>
<petdemo:productItemList numItems="3" productId='<%=request.getParameter("product_id")%>'>
<font size="5" color="green"><%= product.getName() %></font>
<table border="0" bgcolor="#336666">
<tr background="../images/bkg-topbar.gif">
<th><font color="white" size="3">Item ID</font></th>
<th><font color="white" size="3">Item Name</font></th>
<th><font color="white" size="3">Item Price</font></th>
</tr>
<petdemo:items>
<tr bgcolor="#eeebcc">
<td><petdemo:productItemAttribute attribute="id"/></td>
<td>
<petdemo:productItemAttribute attribute="productAttribute"/>
<petdemo:productItemAttribute attribute="name"/>
</td>
<td><petdemo:productItemAttribute attribute="listcost"/></td>
</tr>
</petdemo:items>
</table>
</petdemo:productItemList>
We can see from the <jsp:useBean> tag that
the product.jsp page uses the
CatalogWebImpl bean. This class implements the application
object in a Model/View/Controller pattern by centralizing access to the
collections of data needed by the web tier to render pages for a specific
application task. In this case, the task is browsing products, items, and
categories from the store catalog. This class exposes the task-specific data
model through methods like:
getProduct(),
getProducts()getItem(),
getItems()getCategory(),
getCategories()These methods allow the Web tier developer to access either a
single data item or a collection depending on the situation. The
product.jsp page calls getProduct() to
retrieve an instance of a Product value object corresponding
to the ID passed in the HTTP parameter named product_id. To
display the name of the product in the page, we see the Java scriptlet
<%=product.getName()%> used later in the page, which
calls the getName() getter method.
To show the list of specific product items corresponding to the selected product, the page uses a custom tag library containing tags like:
<petdemo:productItemList>, to
retrieve a list of Item value objects for a given
product
<petdemo:items>, to iterate over the
items in the list
<petdemo:productItemAttribute>, to
display individual item attribute values
Notice that to coordinate the master/detail relationship between
Product information and Item detail information, the page author passes the
product_id parameter value from the master as the value of
the productId attribute on the
<petdemo:productItemList> tag, using a JSP
scriptlet:
<petdemo:productItemList numItems="3" productId='<%=request.getParameter("product_id")%>'>
It's important to note that each of these tags is specific to the
Pet Store Demo product item list and requires code similar to that found in the
demo source code files ProductItemListTag.java,
ItemsTag.java, and
ProductItemAttributeTag.java, respectively. These tags hide
the data binding and formatting code from the JSP page developer. For example,
the ProductItemAttributeTag.java class contains code like
that shown in Example 3 (comments added).
// handle the <petdemo:productItemAttribute attribute="XXXX"/> tagExample 3: Data binding/formatting code from the
if (attribute.equalsIgnoreCase("name")) {
return (product.getName());
} else if (attribute.equalsIgnoreCase("productattribute")) {
return (productItem.getAttribute());
// ...etc...
} else if (attribute.equalsIgnoreCase("listcost")) {
// FORMAT the value of the list cost as currency before returning
return JSPUtil.formatCurrency(productItem.getListCost(), locale);
} else if (attribute.equalsIgnoreCase("description")) {
return (product.getDescription());
// ...etc...
Under the covers, these tag implementation classes
also use the CatalogWebImpl application
object to access the collections of Item value objects
needed to display the details on the page.
As recommended by the Data Access Objects pattern, the data access
code is isolated into a separate class for ease of maintenance, so the
CatalogWebImpl class turns around and uses the
CatalogDAOImpl class that actually executes SQL queries
using JDBC code to retrieve the data. Here the demo illustrates its
implementation of the Fast-Lane Reader pattern, where the application object in
the web tier consciously avoids using EJB Entity Beans to access store catalog
data, going directly to JDBC instead.
Among other things, the code in the
CatalogDAOImpl class embeds the two SQL statements that will
be executed to retrieve the data needed by the product.jsp
page. The getProduct() method in
CatalogDAOImpl contains a line like
String qstr = "select productid, name, descn " +
"from " +
DatabaseNames.getTableName(DatabaseNames.PRODUCT_TABLE, locale) +
" where " +
"productid='" + productId + "'";
to retrieve a product by ID, while the
getItems() method contains this line:
String qstr = "select itemid, listprice, unitcost, " +
"attr1, attr2, a.productid, name, descn " +
"from " +
DatabaseNames.getTableName(DatabaseNames.ITEM_TABLE, locale) +
" a, " +
DatabaseNames.getTableName(DatabaseNames.PRODUCT_TABLE, locale) +
" b where " + "a.productid = '" + productId +
"' and a.productid = b.productid "+ " order by name";
which joins informaton from the PRODUCT and ITEM tables needed to
display the details. Significant additional code in
CatalogDAOImpl.java is also responsible for implementing
behavior like:
Item value objects for the
result set rows on the current page
The Pet Store demo comes with full source code, so open up these classes yourself and take a look. What might come as a surprise is that all of this code must be written to support each query executed by the application. Figure 4 highlights the amount of one-off application plumbing code that is required to display master/detail information on a simple JSP page using a hand-coded approach to the J2EE Design Patterns.

Specifically, the Pet Store Demo's approach to implementing the design patterns demonstrates that you have to implement:
CatalogWebImpl) to cleanly separate the data model needed
to implement the client display for your task (e.g. the set of JSP pages for
the "Browse the Store Catalog" task)
CatalogDAOImpl) to isolate the Fast-Lane
Reader JDBC database access code, and to implement the
Page-by-Page Iterator behavior by skipping over rows from
previous pages while fetching data, and returning a page-sized list of rows for
the current page.
Product, Item) to transfer the
respective database query result rows for products and items queries,
ProductItemListTag,
ProductItemAttributeTag) to implement data binding and
formatting code in a layer that hides these coding details from the JSP page
authors.
And all these steps (along with the code required behind them) were necessary just to get one product and a list of its detail items on the screen!
Perhaps the most disappointing news is that none of these classes is reusable when the time comes to display some other data like Customer information on a JSP page. You have to replicate the code for all the steps above for the customer information, and indeed for each different view of business information that needs to be surfaced to web client displays. Quite a workout!
It's worthwhile to point out that when developers hand-code a
similar solution over and over, in the interest of time they are likely to cut
corners. In fact, experience proves that one of the first aspects of code
quality to suffer is the extra coding required to make optimal use of JDBC.
Unfortunately, cutting corners in the database access layer of your application
has direct and measurable negative impact on your application's performance and
scalability. For example, the JDBC code in
CatalogDAOImpl.java in the Pet Store Demo, does not use JDBC
bind variables, does not reuse prepared statements, does not exploit bulk
record fetching, and does not implement any kind of data caching for frequently
retrieved data, etc. Ideally, all of these additional application plumbing
details to remember should be written once in generic code so all developers on
the team can share their benefits.
As we saw in the quote from Sun's J2EE Blueprints book above, solving this kind of routine, recurring problem cries out for a framework to automate the interaction of the various objects involved. In fact, after implementing your tenth JSP page following the hand-coded pattern example above, you will undoubtedly begin to study the opportunities for automation yourself!
From experience, you notice that for every set of pages that you build related to a particular application task (e.g. displaying your store catalog), you find yourself typing in code that answers the same basic questions:
For your task-specific MVC Application Object implementation:
"What specific views of data do my JSP pages need for this application task?"
For your Data Access Objects, Fast-Lane Reader, and Page-by-Page Iterator implementation:
"What SQL queries does my application need to give the appropriate views of business data?"
"Do any queries represent master/detail links and need to take additional parameters?"
For your data-binding tag library implementation:
"What MVC application object do I want to use on these pages?"
"What views of data are needed, and how many rows per page?"
"What attribute values are displayed, and how should they be formatted?"
You also realize that each of your hand-coded value-objects follows similar coding pattern and could easily be made more generic. These opportunities to generalize your repetitive design-pattern implementation code are reflected in Figure 5.

Given enough time by your management to design, debug, and implement them, you realize that you could significantly simplify your life as a J2EE Design Patterns developer by writing yourself a few generic Java Bean components like:
Aspiring to achieve a good object-oriented design, the behavior of
these generic helper components would live in base classes, like
QueryBeanImpl and
ApplicationObjectImpl. From then
on, any time you need to build a new query or a new application object for a
particular J2EE application you are building, you just derive a new subclass
from the appropriate generic base class. Distinguished metadata like the SQL
query statement, the names and types of the query results column values, or the
names of the views in your application object data model could be stored for
easy editing in an XML deployment descriptor for each derived component. As a
bonus, by centralizing these common implementation aspects of your J2EE
applications, you could then write a generic JSP Tag Library that handles all
of your data binding needs, instead of having to code one for each new kind of
data that needs to be presented.
To be sure, nothing you did while building your time-saving framework compromised your application's J2EE compliance. And, of course, your new, more clever approach still implements the same, familiar J2EE Design Patterns: heck, you designed it on purpose that way! All that's changed is that you're spending less time implementing design patterns plumbing code and more time implementing J2EE applications that make a difference to your company. In this ideal scenario, you find that your new J2EE framework is a gift that keeps on giving...
Back in the real world, it's unlikely that your management has budgeted time in the schedule for you to implement such a framework yourself. However, this fact does not necessarily doom you to a life of hand-coding design patterns. You're in luck, since you can leverage Oracle's off-the-shelf J2EE framework called Business Components for Java (BC4J). It already implements the J2EE design patterns framework described above, so you don't have to.
The BC4J framework comes with an implementation of the time-saving ingredients we described above:
ViewObject implements the Data Access Objects, Fast-Lane
Reader, and Page-by-Page Iterator patterns
Row implements the Value Object pattern
ApplicationModule implements the data model in a
Model/View/Controller pattern, and
Using the BC4J Wizards and Editors you can create subclasses of the generic framework components very easily. The tools manage the creation of editing of both your Java framework subclasses and their XML-based deployment descriptors. The only code you write is code specific to your own application's functionality.
Starting with an empty project in the Oracle 9i JDeveloper development environment, here are the steps required to implement the JSP page from the Pet Store Demo above:
pet.
Use the View Object Wizard to create a view object called
Product with the SQL query:
select productid, name, descn
from product
where productid = ?
Use the View Object Wizard again to create a view object called
ProductItem with the SQL query:
select itemid, listprice as listcost, unitcost,
attr1 as product_attribute, a.productid, name, descn
from item a, product b
where a.productid = b.productid
order by name
Listcost attribute to display as "Currency" with a
mask of "$0000.00"
ItemsForProduct linking the master
Product view with the detail ProductItem
view based on appropriate key attributes specified declaratively
CatalogWeb to be your MVC application object,
and select the master/detail combination of the Product view
and the ProductItem view to define the data model that the
application object will support.
Write a product.jsp page using the in-place
tag library assistance provided in the JDeveloper JSP editor to:
Use the <bc4j:ApplicationModule>
tag to indicate that you want to use the pet.CatalogWeb
application object
<bc4j:ApplicationModule id="catalog" configname="pet.CatalogWeb.TestConfig"/>
Use the <bc4j:DataSource> tag
twice to indicate that you want to use both the Product
query and the ProductItem query. To limit the items query to
only show three rows per page, just set the rangesize
attribute as shown.
<bc4j:DataSource id="product" appid="catalog" viewobject="Product"/>
<bc4j:DataSource id="item" appid="catalog" viewobject="ProductItem" rangesize="3"/>
<bc4j:RowsetIterate> twice
in a nested fashion to iterate the master Product collection
and the nested, detail ProductItem collection
<bc4j:ShowValue> and
<bc4j:RenderValue> tags wherever you need to display
information in the page. The latter automatically leverages formatting hints
like the Currency format mask we added to the Listcost
attribute to display formatted results.
<bc4j:ReleasePageResources/> tag to the end of the
page to free any resources used by the page
Finally, add the one-line JSP snippet to the top of the page
that sets the value of the JDBC bind variable in the Product
query equal to the value of the HTTP parameter named
product_id.
product.getRowSet().setWhereClauseParam(0,request.getParameter("product_id"));
Then run the product.jsp page directly from the
IDE to see the fruit of your labor. It produces the same results as the Pet
Store Demo example, with a whole lot less work on your part. The only line of
code you had to write was the one line above to set a bind variable.
Figure 6 illustrates the resulting set of components that you've
created.

And the JSP page, for comparison, looks like Example 7.
<%-- Lists all items in the inventory for a particular product type. --%>Example 7: BC4J-powered approach: generic tag library and just one line of code
<%@ taglib uri="/technology/webapp/DataTags.tld" prefix="bc4j" %>
<bc4j:ApplicationModule id="catalog" configname="pet.CatalogWeb.Test"/>
<bc4j:DataSource id="product" appid="catalog" viewobject="Product"/>
<bc4j:DataSource id="item" appid="catalog" viewobject="ProductItem" rangesize="3"/>
<%
product.getRowSet().setWhereClauseParam(0,request.getParameter("product_id"));
%>
<bc4j:RowsetIterate datasource="product">
<font size="5" color="green"><bc4j:ShowValue dataitem="Name"/></font>
<table border="0" bgcolor="#336666">
<tr background="../images/bkg-topbar.gif">
<th><font color="white" size="3">Item ID</font></th>
<th><font color="white" size="3">Item Name</font></th>
<th><font color="white" size="3">Item Price</font></th>
</tr>
<bc4j:RowsetIterate datasource="item">
<tr bgcolor="#eeebcc">
<td><bc4j:ShowValue dataitem="id"/></td>
<td>
<bc4j:ShowValue dataitem="ProductAttribute"/>
<bc4j:ShowValue dataitem="Name"/>
</td>
<td><bc4j:RenderValue dataitem="Listcost"/></td>
</tr>
</bc4j:RowsetIterate>
</bc4j:RowsetIterate>
</table>
<bc4j:ReleasePageResources/>
For this particular set of catalog pages, the Pet Store Demo chose not to involve Enterprise Beans, opting instead for the JSP page to directly use the MVC application object, and indirectly the DAO implementation class, as local Java beans classes. However, other pages in the Pet Store demo do make use of session beans. Using the BC4J framework to power your J2EE application development, you can have it either way. You can decide at any time which of your application components should be deployed and used as a local Java beans as shown above, and which should be deployed as EJB Session Beans, supporting the Session Façade pattern. All that's needed is to use the Application Module Editor and select the desired deployment modes on the "Remote" tab as shown in Figure 8.

In the next section we'll describe in detail exactly how BC4J supports the EJB architecture and what options the BC4J developer has available for implementing performant EJB applications for multiple J2EE application servers, including Oracle9iAS and WebLogic.
As prescribed by the design patterns in the J2EE Blueprints and illustrated by the healthy mix of J2EE technologies on display the Java Pet Store Demo, Enterprise JavaBeans are one of the many tools in the J2EE developer's toolbox. Following this spirit, BC4J implements a complete set of J2EE application-building facilities that target EJB 1.1 and EJB 2.0 application servers using a carefully-architected blend of J2EE technologies. The architecture, capabilities, and performance of the BC4J framework have been validated by over two years of extensive, daily use within Oracle's own Applications Development division on projects using JSP, Servlet, Swing, and pure XML user interfaces.
Out of many different possible architectures for building EJB applications, first we'll study the factors that motivate the architecture that BC4J targets.
It's natural that after completing an EJB training course, many first-time J2EE developers see Enterprise JavaBeans as the principal tool in their J2EE toolbox. This innocent initial instinct compels them to create enterprise beans for every component in their application:
However, as these developers load-test their application, they generally discover the system fails to scale due to inherent remoting overhead that Enterprise Beans require. Section 5.5 of the J2EE Blueprints book confirms this, and recommends a simpler, more pragmatic strategy:
"Since enterprise beans are remote objects that consume a significant amount of system resources and network bandwidth, it is not appropriate to model all business objects as enterprise beans. Only the Business objects that need to be accessed directly by a client need to be enterprise beans; other objects can be modeled as data access objects.” (Section 5.5, J2EE Blueprints)
The J2EE design pattern called "Session Façade" further refines this recommendation by clarifying that applications should be designed so that only Session Beans are remotely accessible. Rather than providing fine-grained, remote access to individual business entities to the client, Session Façade suggests creating an EJB Session Bean to wrap access to appropriate views of business information in a task-specific service interface. As shown in Figure 9, Value Object classes shuttle copies of the appropriate subset of business data between the Session Bean and the client program.

Since the recommended Session Façade architecture effectively encapsulates the technology used to represent your persistent business entities, the J2EE platform (the EJB specification in particular) affords several different options for implementing this layer of your application. Under the control of your Session Bean Façade, there are two top-level strategies. You can implement your persistent business components:
As the textbook solution proposed by most introductory texts on EJB, Entity Beans seem like the obvious choice due to their familiarity. However, more advanced EJB books like the J2EE Blueprints propose lightweight Data Access Objects as a pragmatic alternative given the former's inherent remoting overhead. It is clear that, while Entity Beans are undoubtedly the incumbent in this technology election, there is a strong support base for the lightweight DAO solution among communities of J2EE developers that have already "been there, done that" with Entity Beans and who have come back having learned some lessons.
Entity Beans offer both container-managed (CMP) and bean-managed (BMP) persistence options, giving the developer a choice between higher productivity and more flexibility, respectively. In contrast, with the lightweight DAO approach, only the BMP approach is available. CMP Entity Beans would appear the obvious choice, due to the time they can save developers by avoiding hand-written persistence code. However, for both BMP Entity Beans and lightweight DAO's, the potential downside of hand-coding can be avoided through the use of a object/relational mapping framework. So again, the lightweight DAO approach, if powered by a framework, keeps its head in the race.
Since CMP Entity Beans drive their persistence mapping off XML-based deployment descriptors, it's widely held that they are easier to maintain. However, if the persistence framework you use with BMP Entity Beans or lightweight DAO's adopts a similar metadata-driven approach, then again any compelling distinction between the approaches is blurred anew.
CMP Entity Beans offer the promise of being portable among application servers, but again a properly written framework can offer bean-managed database persistence that easily runs in any J2EE application server and indeed can be designed to support multiple back-end databases, too. Yet again, our various options appear equally matched.
Luckily, two final facts help tip the scales in the underdog's direction:
So, as shown in the matrix in Figure 10, an ideal technology combination that offers high productivity, high flexibility, and low overhead is a lightweight Data Access Objects framework with metadata-driven, bean-managed persistence.

This combination provides the convenience and improved maintenance of CMP Entity Beans, since the framework implements the persistence for you based on metadata descriptions. It provides the flexibility and control that only BMP solutions enable, without incurring the chore of hand-coding. This combination achieves portability to the widest array of application servers, since it's a technique supported by both EJB 1.1 and EJB 2.0. And last but not least, it avoids the remoting overhead of EJB 1.1 Entity Beans which the Session Façade pattern makes unnecessary. By design, the business entities are totally encapsulated by the façade so no remoting is needed.
In summary, implementing business entities as lightweight DAO's using a metadata-driven object/relational persistence framework gives all of the benefits, with none of the drawbacks. In combination with EJB Session Beans implementing the Session Façade pattern, it's a technology layer that the J2EE Blueprints book confirms is growing in popularity for efficient J2EE applications:
"Data Access Objects fill a gap in the J2EE application architecture between responsibilities of application developers and those of service providers. They represent an excellent opportunity to add value. In the future, custom DAO’s will most likely be replaced by sophisticated object/relational tools.” (Section 5.5.1.4, J2EE Blueprints)
As we'll see in the next section, this is precisely the unconventional, yet unquestionably J2EE-compliant, technology combination that the BC4J framework provides for J2EE developers desiring an optimal approach with minimum effort.
At its core, BC4J is a metadata-driven Data Access Objects framework. The framework offers J2EE developers time-saving features that add value in all of the tiers of the J2EE application architecture:
In the Business Logic Tier
BC4J simplifies producing EJB Session Beans for efficient business services supporting either Container-Managed or Bean-Managed transactions. These Session Beans implement the Session Façade pattern, and wrap access to efficient, lightweight Data Access Objects that expose Fast-Lane Reader SQL views and implement object/relational persistence.
In the Web Tier
As demonstrated in the Java Pet Store example we explored above, BC4J provides declarative data-binding for JSP pages using a generic tag library that works in tandem with the BC4J Data Access Objects. These same DAO's also simplify XML-based business integration through native support for reading and writing XML datagrams from any view or hierarchical set of related views of data.
In the Client Tier
BC4J provides declarative data-binding for rich JFC/Swing displays through a set of pre-built Swing models and a large number of pre-built data-bound Swing controls.
In this section we'll take a closer look at the key building-block components that make up the framework. Figure 11 shows the architecture of a typical J2EE application built using BC4J.

The figure describes a simple Payment Terms Management application, assembled from the core BC4J framework components:
Customer,
Bill, and Payment are lightweight Data Access Objects that are
designed to encapsulate business logic that is shared across applications and
handle database persistence for your business entities,
SlowPayingCustomers and LatePayments are companion Data Access Objects that
assist in joining, filtering, projecting, and sorting your business information
using the full power of SQL for the specific needs of a given application
scenario or task. View objects can be used on their own to provide efficient,
read-only data access using SQL, or they can be used in cooperation with entity
objects to provide fully-updatable views of information joining data from any
number of underlying business entities.
Bill
entity class can easily call getCustomer() to retrieve its
related Customer instance, and
getPayments() to retrieve the collection of related
Payment instances.
PaymentTermsManagementApp provide a
Model/View/Controller application object implementation, conveniently exposing
a complete data model for a given application task. Application modules can
contain both process and business logic that is specific to a particular
application task. Application modules are deployed as EJB Session
Façades that wrap access to the other data access objects in the
framework. These Session Beans can support either Bean Managed or Container
Managed transactions and can be deployed to J2EE application servers like
Oracle9iAS and WebLogic.
The Oracle9i JDeveloper environment comes with comprehensive tools support for putting the BC4J framework components to use in your J2EE applications. You use interactive wizards, editors, property inspectors, and UML diagrammers to create, enhance, and deploy your BC4J components. Of course, since these tools are tightly integrated within a complete Java IDE that features unparalleled debugging, deployment, and source control support, you can work from the beginning to the end of your J2EE application development lifecycle under one convenient roof.
For example, to build the EJB Session Bean façade for the application in Figure 11, we can start by creating an empty UML class model. We can drop three new entity object classes on the diagram, type their desired class names and interactively add an initial set of attributes directly on the diagram. Next, we can associate the classes on the diagram and set appropriate multiplicity. The result is shown in Figure 12.

As we work, JDeveloper keeps the Java source and XML deployment descriptor for each of our data access objects in synch with any actions we make on the diagram in real time. For example, Figure 13 shows what the System Navigator and Structure Pane look like after creating the UML model above.

We can then use the Entity Object Editor to specify the
object/relational mapping for the Bill,
Customer, and Payment entities, then use
the Create Database Objects wizard to automatically create the desired
relational tables in our database to store the Bill,
Customer, and Payment instances.
For this particular Payment Management application, we need to work
with a collection of just our slow-paying customers, and for each of these
customers, the corresponding collection of their late payments. We can use the
View Object Wizard to create components named
SlowPayingCustomers and LatePayments that
contain the appropriate SQL queries to retrieve just the information we need.
Figure 14 shows one panel of the View Object Wizard in action,
allowing the developer to specify the complete query. When this complete
flexibility is not required, the tool can automatically default the query
statement for you based on the underlying entity object attributes that you
select in an another panel in the wizard.

By introducing a view link component to link these two queries, our
application code can easily work with the master/detail coordinated set of
correlated information that we need. Finally, we can create an application
module component named PaymentTermsManagementApp to group our linked view
components into a single MVC application object for testing and deployment.
Using the handy, built-in Component Browser shown in Figure 15,
we can even test the application module locally before deploying it to the J2EE
server.

Once we're happy with the data access functionality exposed by our framework components, we are just one wizard away from deploying the whole thing as a complete EJB Session Bean to be a Session Façade for our data access objects. Selecting the Deploy... option from the project in the Navigator, we launch the Business Components Deployment Wizard shown in Figure 16. This allows us to chose what kind of EJB Session Bean we want, whether we want it to support a Bean-Managed or Container-Managed transaction, and which EJB server we are targeting.

Once we've made these selections, the wizard will assemble the entire J2EE-compliant EAR file automatically for deployment. In addition, if we're deploying to Oracle9iAS or WebLogic, the tools can help go the final step and actually perform the EAR file deployment directly to the server with no user interaction. In a section below, we'll explain the difference between the "AppModule Session Bean" and the "Service Session Bean" choices in Figure 16 to clarify the difference in functionality that you have to choose from.
First, however, we will take a quick tour to learn about the power that comes from the innovative way in which the view object "query beans" cooperate with the entity object "business beans". This duo are the yin and yang of the BC4J data access objects implementation.
The combination of BC4J view objects and entity objects provides functionality equivalent to what developers can achieve by combining Fast-Lane Reader SQL queries with Entity Beans to handle updates. However, as we'll see in this section, the BC4J data access objects avoid a few gotchas with the Entity Bean approach, while providing lots of additional functionality and better performance.
The J2EE design pattern called "Fast-Lane Reader" suggests that the absolute fastest way to get data into your application is by using JDBC to read the results of a SQL statement yourself:
Sometimes it's more important to access a list of data efficiently, than that the data in the list be up-to-date...The Fast-Lane Reader pattern can accelerate the retrieval of large lists of items from a resource. Instead of going through an enterprise bean, an application accesses data more directly by going through a data access object. (From Sun's Design Pattern Catalog, Fast-Lane Reader page)
As we've seen with other best-practices, this straight JDBC
approach is not something that typical EJB tutorials discuss. Instead they
present the textbook solution of using EJB Entity Bean's
findByPrimaryKey() and user-defined finder methods as the
official way to retrieve data into an application. However, the Fast-Lane
Reader design pattern emerged because:
Since relational databases have evolved to be extremely powerful engines for quickly filtering, projecting, and joining business information, the Fast-Lane Reader pattern basically says, "for fastest results, tell the database what data you need with a SQL statement and just fetch it!" For example, as shown in Figure 17 a Fast-Lane Reader SQL statement can be used to fetch data to populate a collection of value objects to return to the client from an EJB Session Façade.

Figure 17 also illustrates that if the client passes back changed copies of this queried data, these can be made permanent by writing code to directly use the Entity Bean to make the changes. In this way you only pay the price of loading the data you need, and you only bother to load the complete set of entity attributes for the entities that end up getting modified. Since most applications do a lot more reading and writing, this is a winning tradeoff in practice.
There are of course pros and cons to this hybrid approach when using Entity Beans. While just fetching the data you need is fast, it can be inaccurate if there are any pending changes in Entity Beans in the current transaction. If a previous step in the transaction has made a pending update to some attribute of a Product, a subsequent Fast-Lane Reader SQL statement in the same transaction will read the old value directly from the database, and therefore will not reflect the current state of the business object in the current transaction. If this value were, for example, the price of the Product, the inaccurate value might be used in subsequent calculations and cause the inaccuracy to bubble to other attribute values as well.
The BC4J framework's companion data access objects, view object
and entity object, cooperate to maintain the performance benefit of Fast-Lane
Reader without suffering the downside of reading incorrect data. As shown in
steps 1 and 2 of Figure 18, view objects send their SQL query
using JDBC directly to the database (1) and retrieve the results (2) using
optimized JDBC code for best performance. For each row of query results, BC4J
uses its generic Row value object implementation to hold the
results. In this way, view objects provide an implementation of the Fast-Lane
Reader pattern with automatic support for the Value Object pattern, too.

In its XML deployment descriptor, each view object bean you
create keeps metadata that tracks how columns in the SELECT list of their SQL
statement correspond to underlying attributes of related entity objects. In
Figure 18, this metadata is indicated by the dashed lines for
the join SQL query in the EmployeeList view object. The
DEPTNO and DNAME columns in the query
have been mapped to the Deptno and Dname
attribute of the Dept entity object, and the
ENAME, SAL, and EMPNO
columns in the query have been mapped to the Ename,
Sal, and Empno attributes of the
Emp entity object.
The generic view object implementation code exploits this
metadata to automatically delegate the storage of appropriate attributes
retrieved in the query to the underlying entity object instances. These
underlying entity instances are shared between view objects so that common data
retrieved in multiple views is automatically kept consistent. So as illustrated
above, for each row retrieved from the database, the two attributes mapped to
the Dept entity are actually stored under the covers in an
instance of the Dept entity in the cache. Likewise, the
three attributes retrieved in the query that are mapped to the
Emp entity are stored in an instance of the
Emp entity in the cache. If several rows in the query
contain data from department 20, each of these rows points to the common
instance of the Dept entity whose primary key
( Deptno) is 20. For derived attribute values like the
YearsOfService calculated with the SQL expression
TRUNC((SYSDATE-HIREDATE)/365), the view object itself
handles the caching.
Note in Figure 18 that BC4J supports an entity
cache allowing partial entities to exist. Since the LOC
column from the DEPT table and the
HIREDATE column from the Emp table do not
appear in the query, they are not brought into memory. This is a simple
example, but for large entities having 80 to 100 attributes each, this partial
retrieval is a huge savings. Regardless of the underlying caching details, you
work with the query result as an iteratable, updatable collection of
Row value objects. So, for example, to update the value of
the salary of the employee in the current row, you can just call
curRow.setSal(3500), and the framework takes care of the
rest.
Figure 19 illustrates the steps involved when one
of the Row value objects attributes is updated. The same
metadata used above for caching the Fast-Lane Reader query results also comes
into play to enable the automatic delegation that makes the update so easy to
perform.

In step 1, the developer invokes the setter to change the value
of the Sal attribute in the current Row
value object instance. In step 2, the view object row automatically delegates
the setter invocation to the appropriate instance of the underlying
Emp entity object with no user code required. If any
business logic in the Emp entity object class refers to
attributes that are currently missing, like a business rule referencing the
value of Hiredate in our example above, then step 3
illustrates that the entity object implementation will manage the "fault-in" of
all of the entity attributes, based on the primary key. If all entity object
business rules succeed, then the attempt to set the attribute in the internal
entity attribute storage causes the corresponding row to be locked in the
database (step 4) if pessimistic locking is in effect. If the lock can be
acquired, then the value is successfully set in the entity object instance
(step 5). Since entity data is shared, any view objects whose result
collections contain Row value objects with the
Sal attribute of employee number 7788 (step 6) will
instantly see the value change.
Before the transaction is committed by the Session Bean itself or the container, depending on the kind of transaction mode you pick, any subsequent view object Fast-Lane Reader queries that are executed repeat the steps we described above of sending the SQL query directly to the database. Of course, since the pending entity changes have not yet been committed, this queries will fetch the current values from the database. One key difference however when using the BC4J data access objects for your DAO layer, is that the query results will correctly reflect any pending changes in your business entities in the current transaction. That is, using BC4J you avoid the problem of typical Fast-Lane Reader implementations of accidentally working with logically inconsistent data.
This occurs thanks to the cooperation between view objects and
entity objects that we've described in this section, since the entity cache
will favor attribute values with pending changes over known stale values
retrieved from the database. For example, the view object query might retrieve
the value 10, but if that value had previously been modified in the current
transaction to 15, then the user will see value 15. The net result is that the
collection of Row values objects that you work with as the
developer reflects the logically correct values within the current transaction.
Of course, any new rows created in the view object's result collection result
automatically in the appropriate entity instances being created. And similarly,
any rows removed from the collection automatically translated into
remove() calls on the appropriate underlying entity
instances, too. If any associations are programmatically navigated while new,
changed, or deleted changes are pending, the code sees the correct logical
state of affairs reflecting these pending changes.
Finally, when the transaction is committed, the database insert, updates, and deletes for any new, changed, or removed entity instances will be carried out as illustrated in step 7.
Frequently, your application will need to work with join views,
where several of the tables in the join are contributing reference information.
For example, if the user types in the ItemId of
some InventoryItem on a form or page where they
are typing in line items, hand-written code is usually responsible for looking
up the corresponding information like the description, price, and supplier for
the item. Recall that with BC4J, each view object knows which entity objects it
is using and knows that entity objects can be related using associations. This
enables BC4J to keep the reference information synchronized
for you to save you from writing code to
accomplish the task.
Figure 20 illustrates what happens when the value
of the ItemId attribute on the current row in
the LineItemsView is set. It causes the
framework to automatically retrieve appropriate reference information from the
InventoryItem and Supplier entity objects used by the view object. The
shaded pattern on the II and
S indicate the entity references that are
participating in the view as reference entities, rather than being updatable.
This causes the appropriate description, price, and supplier to be
automatically looked up when a user types in a new SKU# with no additional code
required.

As we've seen above, the core components in the BC4J framework are a powerful productivity ally to implement the Data Access Objects layer of your J2EE application. While we've explored the key features of the view object / entity object combination, a number of other interesting capabilities deserve a brief mention before we move on to study what kind of EJB Session Beans you can target with the BC4J framework in the next section.
XML is the lingua-franca for exchanging business information between applications both for application integration and Web Services. The need to rapidly deliver appropriate hierarchical views of business information as XML datagrams is now a core competence for J2EE developers. Using BC4J view objects and view links, you can declaratively build a hierarchy of master/detail SQL queries that deliver exactly the slice of nested business data you need.
Calling writeXML() on your view object
marshalls any or all of its contents as XML, as you desire. For example,
calling writeXML() on the
SlowPayingCustomers view object above might produce an XML
datagram like the one shown in Example 21.
<SlowPayingCustomers>Example 21: XML datagram produced by calling
<SlowPayingCustomer>
<id>101</id>
<name>Big Al</name>
<LatePayments>
<LatePayment>
<id>34112</id>
<bill>9433</bill>
<amount>185.23</amount>
<payDate>2001-08-15</payDate>
<DaysLate>14</DaysLate>
</LatePayment>
<LatePayment>
<id>44563</id>
<bill>9876</bill>
<amount>34.76</amount>
<payDate>2001-09-10</payDate>
<DaysLate>9</DaysLate>
</LatePayment>
</LatePayments>
</SlowPayingCustomer>
<!-- etc. -->
</SlowPayingCustomers>
writeXML()on a view object Even more interesting is the ViewObject's ability to
readXML() to turn the tables and quickly consume incoming
multi-level, XML datagrams. Due again to the clever cooperation between view
objects and entity objects we learned about above, one method call to
readXML() automatically creates, updates, or removes the
corresponding business entity instances under the covers. This includes
automatically enforcing all business rules that have been implemented at the
entity object level. In addition, the writeXML and
readXML methods can work in tandem with XSLT transformations
to produce and consume XML in arbitrary formats.
In addition to working with the generic Row
value object interface, you can optionally choose to generate a typesafe value
object interface like EmpRow which extends the base
Row interface. The difference is that using the generic
Row value object interface, you make method calls
like:
curRow.setAttribute("Salary",new Number(3500));
In contrast, using the optional typesafe value object interface, your code looks like:
curRow.setSalary(new Number(3500));
The typesafe value object option allows the Java compiler to catch more errors at compile time in your code.
We've seen that view objects can easily be used to narrow,
project, and join data from zero or more entity objects. In addition to
producing typesafe value object interfaces that expose a subset or join of
underlying entity data, you can also optionally expose
additional custom methods on the value object interface. This enables your
value object to act as a true Entity Façade. For
example, your custom SlowPayingCustomersRow value object
interface can expose methods like addToWatchList() and
suspendService(). This allows your programmatic or UI client
to iterate the view objects result collection of value objects, and invoke
methods like:
// slowPayers in an instance of a SlowPayingCustomers view object bean
while (slowPayers.hasNext()) {
SlowPayingCustomersRow r = (SlowPayingCustomersRow)slowPayers.next();
if (...) r.addToWatchList();
else if (...) r.suspendService(10);
}
It comes as a surprise to most J2EE developers that Entity
Beans cannot leverage inheritance in the way they expect. In fact in the EJB
2.0 specification, component inheritance is on the list of features under
consideration for a future release of the EJB
specification, after the 2.0 release. With BC4J as your data access objects
framework, whether you use the UML diagrammer or the wizards, creating business
entities that fully leverage component inheritance is as easy as any Java
developer would expect. You can create inheritance hierarchies of entity
objects to model the structure of your business, and easily work with
polymorphic collections of value objects. For example, if you created entity
objects to represent Person, Doctor,
Patient, and Surgeon, you can easily
produce a view object that queries over all people and returns
Row value objects whose underlying entity object instances
are correctly typed as Person, Doctor,
Patient, or Surgeon. The polymorphic view
object support works in tandem with the entity object support for
object/relational mapping of inheritance hierarchies into a single table based
on user-defined descriminator attributes. While other multi-table inheritance
storage strategies are possible by overriding the framework yourself, BC4J
currently implements the default strategy that optimizes SQL queryability
across multiple types of objects in the same "family". In other words, with
Person, Doctor,
Patient, and Surgeon rows stored in a
single table, a simple SQL query can easily query across common attributes
instead of having to use more complicated, and less performant, UNION
queries.
While the BC4J framework's data access objects will work with any SQL92-compliant database, the framework includes unique support for working with an Oracle8i or Oracle9i database, if your company has standardized on the Oracle database. When connected to an Oracle database, BC4J's generic data access objects implementation takes advantage of many performance-enhancing features of the Oracle JDBC driver, including support for:
Number,
Char, and Date to significantly reduce
data conversion overhead
Validation rules are JavaBeans that encapsulate reusable validation code for use across any entity objects where they might be useful. In contrast to the validations performed using Java code written in your entity object's Java implementation class, you attach validation rules to your entity object declaratively through its XML deployment descriptor.
Figure 22 shows the result of using the "Rules"
tab of the Entity Object Editor in JDeveloper to attach a RangeValidationBean to the Quantity attribute of the LineItem entity object. Since validation rules are like
little data-driven validation engines housed inside a JavaBean, they typically
require a set of parameters to be supplied when they are used. These parameters
are captured and represented in the XML deployment descriptor as XML attributes
on the element representing the validation rule usage. This makes the values
easy to set and easy to customize.

Validation rules can be attached both to individual entity object attributes as well as to the entity object as a whole, and the framework supports a collection of zero or more validation rules at each place. validation rules work in concert with Java code-based validation so you can mix and match the approaches as you desire.
While BC4J comes with a set of example validation rules, their real power lies in the fact that you can easily implement validation rules of your own. After all, they're just JavaBeans that implement a supplied Oracle Business Components interface! This lets you provide libraries of reusable validation rules to your development teams or to your end-customer for easy, declarative customization of your application's behavior. Readers familiar with EJB Entity Beans know that they provide no model for implementing declarative business rules, any kind of rule infrastructure for EJB Entity Beans is a "roll your own" proposition.
When building real applications, you frequently find yourself writing little routines to check:
Domains are immutable classes that represent scalar datatypes
that occur often in your applications. Domains to represent the above
situations might be called TelephoneNumber,
CreditCard, WebURL, and FedExTrackingNumber, respectively.
Domains contain a validation in the constructor which performs
the check you need to do to make sure they are proper values. Once-constructed,
instances of Domains can be freely passed around in a type-safe way as method
parameters. In fact, Domains makes it easy to avoid the mistake of passing a
Quantity to a method expecting a
Price since the compiler will flag the error
immediately.
BC4J lets you easily use Domains as the datatype of entity object and view object attributes, which automatically enforces the Domain's built-in validation checks on any attribute values supplied by clients.
To support layered application customization, the BC4J framework is designed to support the factory pattern, allowing customized versions of existing components to substitute for the components from which they inherit at runtime. This allows existing applications to be customized to add new attributes, new business logic, new associations, without having to recompile or change any existing classes or XML deployment descriptors.
Of course, it goes without saying that the JDeveloper IDE provides full design-time support for taking advantage of these framework features. At this point you should have a good idea of the range of pre-built and pre-tested generic data access objects functionality that the BC4J framework can automate for you. Next we'll learn what choices you have for EJB Session Bean deployment.
Using BC4J you can easily build two different kinds of EJB Session Bean Façades:
The Service Session Bean option is typically used when your EJB Session Bean interface must be given to third-party developers to interface programmatically with your application. The AppModule Session Bean option is best when you know that the client to your EJB Session Bean will be a client interface developed by your team (JSP, Servlet, Swing, etc.).
For either option, at deployment time you can select whether you
want to use a Bean-Managed Transaction (BMT) or a Container-Managed Transaction
(CMT). As required by the EJB spec, when deploying as a CMT bean, BC4J
implements the SessionSynchronization interface for you so
the container can drive the transaction boundary. With the BMT bean deployment
choice, the BC4J framework coordinates the call to the expected methods on the
JTA UserTransaction object as a part of its commit
processing.
Let's start by comparing the classic BC4J-powered Service Session Bean to a hand-written one you might build without BC4J, then explain what enhanced features are enabled by choosing the AppModule Session Bean instead. You can change your mind at any time, or try both approaches. Either way, the choice is yours and is as simple as picking the desired selection(s) from a list in the deployment wizard.
Using hand-written Session Façade's, you typically end up coding a solution like the one shown in Figure 23. Your façade class produces collections of hand-written value objects by iterating the results of Fast-Lane Reader SQL statements, or alternatively by iterating the results of calling an Entity Bean finder.

Depending on the implementation of your hand-written value objects, the client either calls setter methods on the existing value object instances or constructs new instances of the value object classes to make changes to the copies of data returned. Then the client passes back a collection of values objects to the Session Façade to make the changes permanent. This last step is accomplished by one of the following:
remove() on it.
create() method on the Entity Bean's home interface and call
setter methods as in (1).
In the example above, we're using a Product
value object. Note that the collection of Product value
objects passed in from the client might contain some new
products, some modified products that were returned in the original collection,
and possibly some removed products. Unless the developer wants to blindly
process each Product passed in by the client, it's his/her responsibility to
provide value object implementations that are smart enough to keep track of
what instances have been modified, newly added, and deleted. In addition,
unless the code inside the Session Façade wants to blindly set each
attribute value, the value object implementation needs to due the necessary
bookkeeping to track which attribute values have changed.
When choosing to deploy your BC4J application module as a classic Service Session Bean, you are able to leverage the features of the BC4J data access objects we've learned about here in your backend enterprise bean implementation. However, as in the hand-written Session Façade above, you are still responsible for:
As shown in Figure 24, your code for constructing the value object collections can benefit by the improved convenience and efficiency of using BC4J view objects, and their update-processing code has the choice of either working directly with their lightweight entity objects (using API's nearly identical to the Entity Bean's), or setting the changes back on the same view object that produced the data originally and let the BC4J view object / entity object cooperation handle making the changes persistent.

The client code to use your classic Service Session Bean is
identical to the client code that you would use for the equivalent hand-written
Session Façade, however the EJB Tier implementation will be more
efficient. For example, Example 25 the code that you might write to
lookup, create, and use the BC4J-powered CatalogService
Session Bean. In this example we call a method on the session bean's remote
interface to return a list of products, then proceed to iterate the list and
update the value of each product's Name attribute to a value
which has the letter "X" tacked on the end of the current value...
Context ctx = new InitialContext(env);Example 25: Client code to work with an EJB Session Bean
CatalogServiceHome home = (CatalogServiceHome)ctx.lookup("CatalogService");
CatalogServiceRemote service = home.create();
Collection c = service.getProductsByStore("SFO-3");
Iterator i = c.iterator();
int row = 0; // Iterate over collection, update product name in even number rows
while (i.hasNext()) {
ProductValueObject pvo = (ProductValueObject)i.next();
if (++row % 2 == 0) pvo.setName(pvo.getName()+"X");
}
service.updateProducts(c);
Deploying your application modules as classic Service Session beans is a good choice when you must publish your EJB interface to third party developers because the API of your service includes only the methods you specify. However, if you are building an application where you are writing both the client and the business logic tier for the application, we'll see the AppModule Session Beans offer a functionally-superior deployment choice. You can easily mix and match these techniques based on the application module at hand, or each deploy the same application module in both ways, so your choice is always very flexible.
While the classic Service Session Bean saves you time and adds value to your EJB tier bean implementation, it is the enhanced AppModule Session Bean that really blows the doors off any hand-written counterpart. In contrast to the classic Service Session Bean, which only supports the remote methods that you create for it, an AppModule Session Bean inherits a rich set of remote collection functionality from the generic BC4J ApplicationModule object.
This means that out of the box, an AppModule Session Bean is equipped to efficiently support all of the J2EE Design Patterns we've discussed in this paper in a fully remotable and extremely network-efficient manner. Of course, it's not just any old Session Bean that can offer a generic implementation of all of these design patterns to save you so much hand-coding of application plumbing. It takes a sophisticated, carefully-engineered Session Bean to offer all this functionality, all the while playing within the rules established by the EJB specification. The fact is, when you deploy your application module as an AppModule Session Bean, BC4J automatically creates an EJB Session Bean whose bean implementation inherits from BC4J's generic implementation of just such a sophisticated bean. So, your AppModule Session Bean façade is, in effect, standing on the shoulders of a helpful giant.
BC4J achieves this network-efficiency for its generic design
patterns functionality by implementing the "Value Messenger" design pattern on
top of the standard EJB home and remote interface for the deployed Session Bean
as shown in Figure 26. BC4J's Value Messenger implementation
ensures that value objects returned to the client as generic Row objects are
both fully-updatable and also kept in synch with the attribute values of the
underlying business components that they represent in the business logic tier.
As Figure 26 illustrates, by manipulating collections of
generic value objects -- RowSets of Rows
in BC4J framework terminology -- values objects can be easily added, modified,
and deleted, with automatic middle-tier synchronization. The Value Messenger
pattern implementation saves you from having to write code to keep the changes
made to your value objects in synch with middle-tier business entities.

By implementing the Value Messenger pattern, BC4J extends the
full set of application module and view object component functionality, and by
implication all the design patterns they implement, seamlessly to the remote
client. The client can navigate page by page through results, create, update,
and delete rows as needed, work with coordinated master/detail collections,
etc., all without the expected network chattiness. Figure 26
illustrates that the client can work directly with the
Product (master) and ProductItem (detail)
collections of generic value objects without additional code. All changes made
to the value objects in the collection on the client are automatically (and
network-efficiently) synchronized at appropriate intervals with their EJB Tier
counterparts. The picture also shows that the coordination between view objects
and entity objects remains in the realm of the EJB Tier
implementation. The client of an AppModule Session Bean
sees and manipulates the world through the generic value objects in the view
object result collections. This keeps the client API very simple.
How is this functionality achieved? Let's take it step by step.
When you look up the CatalogService AppModule Session Bean,
the BC4J JNDI InitialContext implementation caches the
actual CatalogServiceHome interface returned by the EJB
server, and instead returns to the client a generic ApplicationModuleHome interface that is used to
create() the CatalogWeb application
module. As a client developer, you continue to work with the application module
component using the same interface that you would have used on the server-side,
however the implementation beneath that interface in the remote client
implements the smart proxy functionality.
The thin layer of proxy code in the EJB client handles delegating
any activity on the CatalogWeb application module interface
(or any of its contained view object interfaces), through the actual EJB
Session Bean remote interface at the appropriate times. Using the AppModule
Session Bean, the client code looks the same, but no additional hand-written
value-object code is needed from the developer and no additional server-side
create/modify/remove logical needs to be coded. The equivalent client code
looks like what's shown in Example 27.
Context ctx = new InitialContext(env);Example 27: Client code to work with an EJB (AppModule) Session Bean
ApplicationModuleHome home = (ApplicationModuleHome)ctx.lookup("CatalogWeb");
CatalogWeb service = (CatalogWeb)home.create();
RowSet rs = service.getProductsByStore("SFO-3");
RowIterator i = rs.createRowSetIterator();
int row = 0; // Iterate over collection, update product name in even number rows
while (i.hasNext()) {
Row pvo = i.next();
if (++row % 2 == 0) pvo.setAttribute("Name",pvo.getAttribute("Name")+"X");
}
// Don't need to call an explicit Session Bean method to update the rows
// But you can have a method on the AppModule interface that accepts
// a RowSet argument to simulate the same kind of API as the bean above
service.updateProducts(rs);
Note that the generic ApplicationModuleHome
stands in for a specific session bean home, since the BC4J JNDI
Context implementation introduces a thin indirection layer
over the basic EJB Session Bean home and session bean remote interfaces to
allow for numerous network traffic optimizations achieved through local
caching. The small library of client-side implementation code behind the BC4J
generic Design Pattern interfaces, automatically handles
the EJB lookup and create, and hangs onto the actual interfaces and delegates
calls through them as needed.
Note, the use of the generic RowSet list
interface and the generic Row value object instead of
hand-written, one-off value object classes used in the classic Service Session
Bean example above.
Taking advantage of a further convenience that
RowSetimplements RowIterator by providing a built-in, default iterator
implementation, and illustrating the use of optional type-safe custom value
object interfaces ( ProductRow here, instead of using the
base Row interface), the example above can be shortened to
look like Example 28.
Context ctx = new InitialContext(env);Example 28: Using custom row interfaces to improve type-safety checking
ApplicationModuleHome home = (ApplicationModuleHome)ctx.lookup("CatalogWeb");
CatalogWeb service = (CatalogWeb)home.create();
RowSet rs = service.getDepartments();
int row = 0; // Iterate over collection, update product name in even number rows
while (rs.hasNext()) {
ProductRow pvo = (ProductRow)i.next();
if (++row % 2 == 0) pvo.setName(pvo.getName()+"X");
}
// Pass collection of partially-modified values objects back to server
service.updateProducts(rs);
These are simple, programmatic examples, but of course, all of the additional generic client functionality, like the generic JSP tag library and the generic JFC/Swing data bound controls work seamlessly over this remote AppModule Session Bean deployment, too. In the next section we drill down further on how BC4J implements the Value Messenger pattern to achieve these results.
| NOTE: |
Readers unfamiliar with EJB Session Bean implementation details may opt to skip to the next section |
Instead of using straight Java classes with member variables to hold the value object attributes, the more sophisticated BC4J value object implementation automatically leverages a client-side value object cache to implement both network traffic optimization and middle-tier value object synchronization. So when you deploy an application module as an AppModule Session Bean, BC4J generates a thin layer of client proxy implementation classes to support your tier-independent component interfaces. These client classes implement the component interfaces that your client program uses to work with your application data model and custom application module methods. As we'll see in this section, your coding style does not need to change to take advantage of the additional features of Value Messenger.
Because BC4J's implementation of the generic
Row value object leverages a client-side value object cache
for storage, you can make changes to several attributes of your value objects
without incurring network round trips for each attribute changed. Once all
necessary changes have been made, the pending changes to value object values
sitting in the client cache are sent in bulk to the EJB tier in a single round
trip. In addition, as part of that same network round trip, any EJB Tier
attribute values that changed as a side effect of the current middle-tier
synchronization are sent back in in bulk in a "Value Message" to refresh the
corresponding value object attributes in the client.
An example, illustrated in Figure 29, will
help clarify how the mechanism works. Suppose you've built an application
module component that uses a single view object
EmployeeList, related to two underlying entity objects
Dept and Emp. Assume that business logic
written in the Emp entity object implementation class forces
any Ename attribute value set to be in uppercase:
public void setEname(String value) {
if (value != null) value = value.toUpperCase();
setAttributeInternal(ENAME, value);
}
Furthermore, imagine that additional Emp
entity busines logic enforces the business policy that if an employee's salary
is set to a value greater than $3000, then their vacation limit is
automatically increased to 144 hours.
As shown in Figure 29 in step 1, the client
can set the Sal attribute of the value object to 3500 and
set the Ename attribute to "Steve". The pending changes are
kept in the client-side value object cache. In step 2, an operation like UI
navigation, explicit transaction commit, or explicit EJB Tier method invocation
causes the changes to be sent to the middle tier in bulk. As part of the value
object synchronization, the Sal and Ename
attributes are set in the appropriate entity object instances in the cache
(Step 3) using the view object / entity object coordination we've studied
earlier. The business logic in the Emp entity object causes
the value of Ename to be uppercased and the value of
VacationLimit to be set to 144 (Step 4). All relevant
changes to value object attributes of interest to the client cache are bundled
and returned as part of the network roundtrip to the client. In this example,
the uppercased value "STEVE" and the updated value 144 of the
VacationLimit attribute are returned to the client (Step 5).
Finally, in Step 6, the client value object "sees" the middle-tier updates and
renders on the screen/page with the latest values. Of course, you don't need to
write any application plumbing code to make any of this happen since your bean
inherits the Value Messenger pattern implementation from the application module
framework base class ApplicationModuleImpl.

Without leveraging a Value Messenger pattern implementation of some kind, your client-side value objects remain stale copies of business data and are not updated to reflect changes that have occurred in the EJB tier due to routine business logic execution. In addition, as we've seen in previous sections, the task of updating EJB Tier business entities based on changes made to client value objects is left as an exercise for the coder.
It's interesting to examine a few details of how BC4J implements
the Value Messenger pattern in practice. Consider an application module named
MyApp with a custom method that you publish on the
application module's remote interface:
// Your application module component implementation class
public class MyAppImpl {
// A custom method to be remotely accessible
public Integer someMethod(String x, Number y) {
// do some middle-tier business functionality and return an Integer
}
}
When you deploy your application module component as an AppModule
Session Bean, the Session Bean Façade and Value Messenger implementation
are automatically generated for you and shown in the UML class model in
Figure 30. Note that in order to handle sending the bulk "value
message" from the client to the EJB Tier, the signature of each custom method
is augmented with an additional byte-array parameter. Also, to handle returning
the bulk "value message" from the EJB Tier as a part of the method invocation,
each custom method's return value is changed to be of type
PiggybackReturn and code is generated to include the actual
method return value as part of this "piggyback" object.

Luckily, as the application client you are shielded from knowing
or caring about these implementation details. As shown in
Figure 31, your client code works with the tier-independent
MyApp interface, which has exactly the same signature as
your custom method in your application module implementation class.

The BC4J-generated client proxy objects that implement this interface worry about the details of sending any pending value object changes to the EJB tier, and worry about refreshing the client value object cache with any EJB tier value object attribute changes.
Above we've explored the various ways to deploy BC4J application modules as EJB Session Bean façades. However, it's important to remember that many of today's J2EE applications are based purely on servlets and/or JSP's that access Java code in local classes. That is, they are J2EE applications that exploit the J2EE Web Tier but haven't yet embraced the J2EE EJB Tier. If you count yourself among the developers that haven't yet made the move to EJB, not to worry. BC4J-powered applications leave the J2EE deployment architecture decision to the developer and keep your options open throughout the lifecycle of your application.
The BC4J framework encourages a well-architected, coarse-grained "service façade" application architecture whether you decide to deploy your application module as an EJB Session Bean, or not. This means that any application module can also be deployed and used in "local mode" -- that is, as a simple Java bean -- to support application architectures that exclusively target the J2EE Web Tier. At any time in the future, by revisiting the Application Module Editor in Oracle9i JDeveloper, you can redeploy the same application module as an EJB Session Bean with no code changes to your application. So adopting the BC4J framework for your J2EE application development not only saves you from writing a lot of Design Patterns application plumbing code, but also gives you the deployment flexibility to plan your EJB Tier uptake when it makes most sense for your application development team.
The core BC4J framework implements the model layer of a Model/View/Controller architecture, giving you powerful features to work with data in any way you need to, update that data if neeeded, and automatically engage reusable business logic in the process. In addition, since application modules are a convenient place to write custom, task-specific methods that appear on your EJB Session Bean Façade, some users take advantage of this capability and write their "Controller" logic directly into their application module class for simplicity.
Either way, you have a lot of flexibility when implementing the "View" and "Controller" layers of your BC4J-powered J2EE application. Oracle9i JDeveloper ships with several complementary client frameworks that assist in implementing this part of your application. All of them feature built-in support for working with BC4J application modules, so by combining BC4J with these additional UI frameworks, your development productivity is further enhanced.
J2EE Web Tier state management is one of the most common and most onerous development tasks facing web application developers. Web Tier state management comes into play when a logical application task requires the user to visit multiple pages to get the job done. All of the pending work must be saved "between pages" so that it can be committed or rolled back as a unit when the process it complete. However, this is easier said than done.
For example, imagine a web-based expense reporting system. To file a new expense report, a user needs to visit several pages to add, edit, and review multiple expense report entries before ultimately submitting the final report. With a traditional client/server application, this pending state is kept in the memory of a dedicated user process which uses a dedicated database connection. However, since web applications often need to scale to a large number of users, dedicating a server-tier process and a database connection to each web user is not practical.
Since web application developers generally choose stateless application architectures to address this scalability requirement, they need to invent a scheme to save away the pending work to a temporary store after each page request. To make this task simple, BC4J application modules support the ability to serialize their pending state to a convenient XML format at any time, and to instantly refresh their state from such pending-work "snapshots" at any time.
In addition, BC4J comes with an application module pooling framework that automates the use of this built-in "state snapshot" feature to manage pending web-user application state between page requests without requiring developer-written code. Pending state is snapshotted and saved to a central database to support web farm deployment configurations and to allow failover between different web listeners. The pool manages a dynamically allocated set of application module instances -- or client references to remotely deployed instances in the case of EJB Session Bean deployment -- to deliver a "stateless with affinity" web-tier state management approach.
"Stateless with affinity" means that across multiple page requests, the pool attempts to give the web user the application module instance that he was using on the last request if it is still available in the pool and hasn't been used by another web user in the meantime. If the same instance is not available, then any available instance is grabbed from the pool and the pending state of the application module is restored based on the persisted session state snapshot. This technique has proven in large-scale tests by the Oracle Applications development teams using BC4J to deliver excellent performance.
An additional way to improve performance for web applications is to share mostly read-only data across web users. The application module pool supports this by allowing application module instances of your choosing to be shared in a thread-safe way across clients. By doing this, access to common lookup information can be accelerated by avoiding requerying.
BC4J Data Tags are a JSP 1.1-compatible tag library for easily rendering, navigating, and updating data from any view object in any application module. The example in the first section of this paper that illustrated rebuilding the master/detail web page from the Pet Store demo made use of these BC4J data tags. Oracle9i JDeveloper contains integrated support for using the Data Tags in your JSP pages, including wizard-driven tag assistance and context-sensitive "Tag Insight" help for always knowing what tags and attributes are legal anywhere you're typing in your page. In addition, JDeveloper supports running and debugging JSP pages locally for an even quicker test-fix-retest cycle, avoiding a deployment step while you're still in development.
The Oracle JClient framework simplifies building databound Swing-based applications and applets by providing implementations of Swing models that handle the communication between the client UI controls and the BC4J view objects. Using wizards you can quickly produce databound forms using any model-based controls, including standard Swing controls, JClient controls, and third-party addin controls. Applications built with the JClient framework can also use Sun's Java Web Start to take advantage of this new web-based deployment paradigm for rich Java displays. Oracle9i JDeveloper contains integrated support for visually designing and modifying the layouts for your Swing-based UI panels.
The Oracle XSQL Pages Framework makes publishing XML-driven information over the web a snap. Oracle9i JDeveloper ships with additional XSQL action handlers to easily include XML information from any BC4J view object, as well as easily update any view based on incoming XML documents. Any XML published through XSQL pages can also be combined with XSLT stylesheets for convenient transformation into any target XML, HTML, or text-based format. Support in JDeveloper for running and debugging XSQL pages is similar to that offered for JSP pages mentioned above.
The Oracle UIX web application framework simplifies the implementation of complete, sophisticated web applications -- for example, a multi-lingual, self-service Human Resources application -- by providing reusable technology to assist with many of the aspects you would typically have to write code to handle yourself. For example, UIX provides off-the-shelf assistance with web page rendering, data binding, event handling, page-to-page navigation, and customization. It offers a comprehensive set of pre-built page layout elements to deliver web applications with a rich, consistent look and feel across many different client agent types. Of course, as illustrated in Figure 32, UIX provides built-in support for BC4J data-binding, too, so including or modifying data from any BC4J view object is easy.

The Oracle UIX technologies can be used programmatically or declaratively via UIX XML page templates, as well as from with JSP pages using the UIX JSP tag library. Oracle9i JDeveloper features context-sensitive "Tag Insight" for the UIX XML elements and JSP tags, as well as a runtime preview facility to immediately see what your combination of layout components will look like in the browser.
The UIX Controller servlet implements the Front Controller design pattern and coordinates the use of other aspects of the UIX framework technologies as shown in Figure 33.

If none of the built-in options for client development suits your needs or development style, then it's easy to combine J2EE applications built using BC4J with third-party web application frameworks, or a framework of your own design. All of the API's used by the options above to enable automatic data-binding are available and documented for use by your own client-framework code. In fact, Oracle Consulting have leveraged this fact to develop the Oracle9i MVC Framework (formerly known as "JHeadstart" and "Project Cleveland"). This offering, to be made available for download on Oracle Technet, adds metadata-driven page generation facilities and a state-model-based page flow capability on top of the UIX framework and BC4J technologies.
The BC4J framework team at Oracle has been promoting the Session Façade architecture with lightweight, local Data Access Objects even before there were official J2EE Design Pattern names for them. The EJB 2.0 specification, officially released a few months ago in its final form on August 14, 2001, introduces the notion of local interfaces, which allow other beans in the business logic tier to use entity beans without making a remote method invocation. Under this new version of the EJB specification, a data access object can be implemented as a lightweight entity bean, whose local interface abstracts data access functionality.
In addition to adding "Local Entity Beans" (analogous to BC4J's lightweight, local entity object classes), EJB 2.0 also introduces container-managed relations that provide functionality analogous to BC4J's navigable entity associations that we've seen briefly in this paper. Since this is a period of transition for EJB App Server vendors, including Oracle, the BC4J team has chosen in the Oracle9i JDeveloper release to continue targeting both EJB 1.1 and EJB 2.0 application servers. To this end, we've maintained the lightweight entity object classes for this release.
As Oracle9iAS, WebLogic, and other J2EE application server vendors begin to rollout complete support for the new EJB 2.0 specification in the first half of 2002, a new release of the BC4J framework will be released which includes support for the new local entity beans. This work entails enhancing our lightweight, local entity classes to support the necessary interface to be lightweight EJB 2.0 Local Entity Beans. At present, we don't expect these enhancements to require changes to your application code to take advantage of.
So while we have pushed for and applaud the inclusion of the lightweight, local entity beans in EJB 2.0, unfortunately the specification's authors ran out of time to include important features like an ORDER BY statement in the EJB-QL query language, support for Entity Bean component inheritance, and the ability to use the SQL language in finder methods without resorting to vendor-specific extensions. The collective experience of our 2000 internal application developers tells us time and again that you cannot write performant applications unless you fully embrace the ability to exploit the SQL language to squeeze the best performance out of the database. As a key member of the EJB 2.1 and J2EE 1.4 design efforts in the Java Community Process, Oracle will continue to bring its data access and application-building expertise to bear on the J2EE platform and push to improve its application-building facilities in future versions of the EJB specification.
We've seen through numerous examples in this paper that applications built leveraging the BC4J framework are not only fully J2EE-compliant and make optimal use of your application server's EJB 1.1 or EJB 2.0 architecture, but also benefit from a generic implementation of all the important J2EE Design Patterns. We learned that BC4J offers a great developer productivity boost, both for developers working with EJB as well as those still targeting only the J2EE Web Tier. As more and more teams appreciate and begin to reap the productivity benefits that a framework-based approach to J2EE development offers, the BC4J framework and its design-time tools built into Oracle9i JDeveloper will continue to add innovative features to keep BC4J-powered J2EE teams ahead of the pack.
This section provides a handy summary of the J2EE Design Patterns that BC4J implements for you. Some of these are the familiar patterns from Sun's J2EE Blueprints book, and some are design patterns that BC4J adds to the list.
| Pattern Name | Description | How BC4J Implements It |
|---|---|---|
| Data Access Objects | Avoids unnecessary marshalling overhead by implementing dependent objects as lightweight, persistent classes instead of each as an Enterprise Bean. Isolates persistence details into a single, easy to maintain class. | BC4J view objects automate the implementation of data access for reading data using SQL statements. BC4J entity objects automate persistent storage of lightweight business entities, an EJB 1.1-compliant implementation of the EJB 2.0 "local entity bean", not yet available in many EJB servers due to the emerging nature of the EJB 2.0 specification. BC4J view objects and entity objects cooperate to provide a sophisticated, performant data access objects layer where any data queried through a view object can optionally be made fully updatable without writing any "application plumbing" code. |
| Model/View/Controller | Cleanly separates the roles of data and presentation, allowing multiple types of client displays to work with the same business information. | The BC4J Application Module Session Bean provides a generic implementation of a Model/View/Controller "application object" that simplifies exposing the application data model for any application or service, and facilitates declaratively specifying the boundaries of a logical unit of work. Addtional UI-centric frameworks and tag libraries provided in Oracle9i JDeveloper help the developer implement the View and Controller layers. |
| Session Façade | Avoids inefficient client access of Entity Beans and inadvertent exposure of sensitive business information by wrapping Entity Beans with a Session Bean. | BC4J application modules are designed to implement a coarse-grained "service façade" architecture in any of their supported deployment modes. When deployed as EJB Session Beans, they provide an implemention the Session Façade pattern automatically. |
| Value Object | Avoids unnecessary network round-trips by creating one-off "transport" objects to group a set of related attributes needed by a client program. | BC4J provides an implementation of a generic Row object, which is a metadata-driven container of any number and kind of attributes that need to be accessed by a client. The developer can work with the generic Row interface and do late-bound getAttribute("Price") and setAttribute("Quantity") calls, or optionally generate early-bound row interfaces like OverdueOrdersRow, to enable type-safe method calls like getPrice() and setQuantity(). Smarter than just a simple "bag 'o attributes" the BC4J Row object can be introspected at runtime to describe the number, names, and types of the attributes in the row, enabling sophisticated, generic solutions to be implemented. |
| Page-by-Page Iterator | Avoids sending unnecessary data to the client by breaking a large collection into page-sized "chunks" for display. | BC4J provides an implementation of a generic RowSet interface which manages result sets produced by executing View Object SQL queries. RowSet allows the developer to set a desired page-size, for example 10 rows, and page up and down through the query results in these page-sized chunks. Since data is retrieved lazily, only data the user actually visits will ever be retrieved from the database on the backend, and in the client tier the number of rows in the page can be returned over the network in a single roundtrip. |
| Fast-Lane Reader | Avoids unnecessary overhead for read-only data by accessing JDBC API's directly. This allows an application to retrieve only the attributes that need to be displayed, instead of finding all of the attributes by primary key when only a few attributes are required by the client. Typically, implementations of this pattern sacrifice data consistency for performance, since queries performed at the raw JDBC level do not "see" pending changes made to business information represented by Enterprise Beans. | BC4J View Objects read data directly from the database for best performance, however they give developers a choice regarding data consistency. If updateability and/or consistency with pending changes is desired, the developer need only associate his/hew View Object with the appropriate Entity Objects whose business data is being presented . If consistency is not a concern, View Objects can simply perform the query with no additional overhead. In either case, the developer never has to write JDBC data access code. They only provide appropriate SQL statements in XML descriptors. |
| Front Controller | Centralizes view management (navigation, templating, security, etc.) for a Web application in a single object that handles incoming client requests. | The Oracle UIX web application framework's UIX Controller servlet implements this design pattern, managing page rendering, event handler, page flow, etc. |
| Factory Pattern | Allows runtime instantiation of an appropriate subclass of a given interface or superclass based on externally-configurable information. | All BC4J framework component instantiation is effected through factory classes allowing runtime substitution of specialized components to facilitate application customization. |
| Entity Façade | Provides a restricted view of data and behavior of one or more business entities. | The BC4J view object can surface any set of attributes and methods from any combination of one or more underlying entity objects to furnish the client with a single, logical value object to work with. |
| Value Messenger | Keeps client value object attributes in synch with the middle-tier business entity information that they represent in a bidirectional fashion. | BC4J's value object implementation coordinates with a client-side value object cache to batch attribute changes to the EJB tier and receive batch attribute updates which occur as a result of middle-tier business logic. The BC4J Value Messenger implemenation is designed to not require any kind of asynchronous messaging to achieve this effect. |
Yes.
The BC4J framework works with any J2EE-compliant application server. The Oracle9i JDeveloper IDE supports automatically packaging a BC4J-powered J2EE application for deployment to any J2EE 1.2 container. In addition, if you are using Oracle9iAS or WebLogic containers, in addition to this packaging assistance, the tool can automatically carry out the deployment for you, too.
Yes. Any SQL92-compatible database.
By default the BC4J framework takes specific advantage of the Oracle database and features of the Oracle JDBC Driver to maximize application performance, however by using the runtime-configurable "SQL Flavor" parameter, applications built with BC4J can target non-Oracle databases as well. In particular, the Oracle9i JDeveloper release of the BC4J framework has been tested against IBM's DB2 database and Microsoft's SQL Server database (using Merant DataDirect drivers).
No.
The BC4J framework has been carefully designed and optimized to avoid runtime overhead for features of the framework that are not being used. For example, BC4J entity objects are designed to encapsulate business logic and handle persistence. If you use them only to handle persistence, perhaps leaving business logic enforcement to existing database triggers in your database, then you do not pay runtime overhead for business logic enforcement that you are not using. Similarly, the BC4J framework supports various kinds of lightweight listeners that developers can use to be notified when interesting framework lifecycle events occur. Again, if there are no event subscriptions, there is no overhead associated.