You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by Brian McCallister <mc...@forthillcompany.com> on 2003/08/07 20:02:50 UTC
[PATCH] tutorial1.xml updates
Mostly minor fixes scattered throughout, including updating the sample
repository to 1.0 from .9.1
-Brian
On Thursday, August 7, 2003, at 07:13 AM, Mahler Thomas wrote:
> Hi Brian,
>
>> One of the things listed as still missing for 1.0 is improved docs -
>> however I am unable to really find anything in Scarab related (except
>> improving ObjectCache docs).
>
> AFAIK there are no such entries in Scarab. IMO we have fixed most
> documentation issues.
> Of course there is always place for improvements.
>
> So it may be a good idea to review the existing stuff for
> - accurracy
> - completeness
> - language and style
>
> cheers,
> Thomas
>
>> If anyone can give me a pointer as to what they see as needing work I
>> will tackle it immediately.
>>
>> -Brian
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
>> For additional commands, e-mail: ojb-dev-help@db.apache.org
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-dev-help@db.apache.org
>
Re: [PATCH] tutorial1.xml updates
Posted by Armin Waibel <ar...@code-au-lait.de>.
Hi Brain,
> Argh, the attachement problem.
>
> Patch inlined:
please send me the updated files (or RCS's)
directly, then I will check in.
regards,
Armin
----- Original Message -----
From: "Brian McCallister" <mc...@forthillcompany.com>
To: "OJB Developers List" <oj...@db.apache.org>
Sent: Thursday, August 07, 2003 8:06 PM
Subject: Re: [PATCH] tutorial1.xml updates
> Argh, the attachement problem.
>
> Patch inlined:
> --------------------------------
>
> Index: xdocs/tutorial1.xml
> ===================================================================
> RCS file: /home/cvspublic/db-ojb/xdocs/tutorial1.xml,v
> retrieving revision 1.20
> diff -u -r1.20 tutorial1.xml
> --- xdocs/tutorial1.xml 20 Jul 2003 20:37:25 -0000 1.20
> +++ xdocs/tutorial1.xml 7 Aug 2003 18:00:29 -0000
> @@ -17,14 +17,14 @@
> (OJB) object/relational mapping in a simple application
scenario.
> The
> tutorial application implements a product catalog database with
> some
> basic use cases. The source code for the tutorial application is
> - shipped with the OJB source distribution and resides in the
package
> - <B><code>org.apache.ojb.tutorial1</code></B>.
> + shipped with the OJB source distribution and resides in the
> + <B><code>src/test/org/apache/ojb/tutorial1/</code></B> directory.
> </p>
> <p>
> This document explains the architecture of a simple application
> which
> - uses the ObJectRelationalBridge API (PersistenceBroker) to
> + uses the ObJectRelationalBridge PersistenceBroker API to
> implement five use cases which include persistence operations
> (retrieval,
> - storage, deletion of objects). This document will also
demonstrate
> how a
> + storage, and deletion of objects). This document will also
> demonstrate how a
> simple persistence object <code>Product</code> is mapped to a
> table in
> a relational database.
> </p>
> @@ -32,7 +32,7 @@
>
> <subsection name="The Tutorial Application">
> <p>
> - The sample application is a console based data entry application -
> + The sample application is a console based data entry
application --
> a program to manipulate a product catalog database with five
simple
> use cases:
> </p>
> @@ -40,7 +40,7 @@
> <ol>
> <li>
> <b>List all Products</b> -
> - display all products from the persistent store.
> + display all products from the persistent store
> </li>
> <li>
> <b>Enter a new Product</b> -
> @@ -77,8 +77,8 @@
> OJB. This is accomplished via Ant build scripts which are
executed
> by a script in the "bin" directory of the OJB distribution.
(Note:
> This tutorial assumes that you have already downloaded the OJB
> - source distribution.) Note: There is no need to configure a
> - database in order to run these applications. The tutorial
> applications
> + source distribution.) There is no need to configure a
> + database in order to run these applications. The tutorial
> applications
> ship with HSQLDB integration, all you need to do is run the
> prepare-tutorials Ant target.
> </p>
> @@ -136,7 +136,7 @@
> </p>
> <p>
> The <code>Application.run()</code> method runs a main event
loop.
> The
> - program waits for user input in
> <code>Application.selectUserCase()</code>.
> + program waits for user input in
> <code>Application.selectUseCase()</code>.
> Once a UseCase is selected, it is executed via the
> <code>UseCase.apply()</code> method. This UseCase class is a
> simple
> implementation of the well-known Command design pattern.</p>
> @@ -207,21 +207,26 @@
> database access.
> </p>
> <p>
> - You will find the source for the PersistenceBroker API in the
> - package <code>org.apache.ojb.broker</code>.
> - <A HREF="javadoc/org/apache/ojb/broker/package-summary.html">The
> - JavaDoc is here</A>. The key component in this package is the
> - interface <code>PersistenceBroker</code>. It
> - provides methods for retrieval, storage and deletion of objects.
To
> - use it in your application you must know how to retrieve a Broker
> - instance, how to configure its O/R mapping repository and how to
> use
> - the available functionsI.
> + You will find the source for the <a
> +
> href="javadoc/org/apache/ojb/broker/package-
> summary.html">PersistenceBroker
> + API</a> in the package <code>org.apache.ojb.broker</code>. The
key
> + component in this package is the interface
> <code>PersistenceBroker</code>.
> + It provides methods for retrieval, storage, and deletion of
> objects. To use
> + it in your application you must know how to retrieve a
> + <code>PersistenceBroker</code> instance, how to configure its O/R
> mapping
> + repository and how to use the available functions.
> </p>
>
> <subsection name="Obtaining a Broker Instance">
> <p>
> - How do we obtain a Broker instance? Take a look at the public
> constructor
> - of the Application class to find the answer to this question.
> + The <code>Application</code> class's public constructor
> demonstrates how to
> + obtain a <code>PersistenceBroker</code> instance:
> + <!--
> + Is this the best way to demonstrate use of a Broker?
Broker's
> are
> + pooled, but this application uses the same one forever. As
> this is
> + a single threaded application it doesn't hurt, but an awful
> lot of people
> + are using PB's in servlet based, multi-threaded, development
> + -->
> </p>
> <source><![CDATA[
> public Application()
> @@ -246,24 +251,26 @@
> ]]></source>
> <p>
> The PersistenceBrokerFactory creates an instance of
> PersistenceBroker
> - using the resource ./repository.xml as a mapping repository (more
> - details on this repository in the <A HREF="#def_or">section on
the
> - Object/Relational mapping</A>. The PersistenceBroker instance is
> + using the resource <code>repository.xml</code> as a mapping
> repository (more
> + details on this repository in the <a href="#def_or">section on
the
> + Object/Relational mapping</a>. The PersistenceBroker instance is
> passed to the constructor of the four UseCase objects which
> store this PersistenceBroker instance as a protected member
> variable.
> </p>
> </subsection>
> <subsection name="Retrieving Collections and Iterators">
> <p>
> - The next thing we need to know is how to use this broker instance
> to implement
> - our persistence operations. In this use case, we have to retrieve
a
> - collection containing all product entries from the database. To
> - retrieve a collection containing objects matching some criteria
we
> can use
> - <code>PersistenceBroker.getCollectionByQuery(Query query)</code>.
> - Where <code>Query</code> is a class that allows to specify
> criteria like
> - price > 100 or userId == 3. In our case we want to select
> <I>all</I>
> - of the persistence objects stored in the Product table. We need
> <b>no</b>
> - (or <i>null</i>) filtering criteria.
> + The next thing we need to know is how to use this broker instance
> to
> + implement our persistence operations. In this use case, we have
to
> retrieve
> + a collection containing all product entries from the database. To
> retrieve a
> + collection containing objects matching some criteria we can use
> + <code>PersistenceBroker.getCollectionByQuery(Query query)</code>.
> Where
> + <code>Query</code> is a class that allows specification of
> criteria such as
> + <code>price > 100</code> or <code>userId == 3</code>. In this
> case we
> + want to select <i>all</i> of the persistence objects stored in
the
> + <code>Product</code> table. We need <b>no</b> (or <b>null</b>)
> filtering
> + criteria. According to the ODMG the Collection containing all
> instances of
> + a persistent class is called an <b>Extent</b>.
> </p>
> <p>
> Here is the code of the
> <code>UCListAllProducts.apply()</code>method:
> @@ -273,10 +280,9 @@
> public void apply()
> {
> System.out.println("The list of available products:");
> - // build a query that selects all objects of Class Product,
> - // without any further criteria according to ODMG the
> - // Collection containing all instances of a
> - // persistent class is called "Extent"
> +
> + // build a query which selects all objects of class Product,
> + // without any further criteria
> Query query = new QueryByCriteria(Product.class, null);
> try
> {
> @@ -305,7 +311,8 @@
> provides a more efficient mechanism for iterating through all the
> available products. If your application does not need to
maintain a
> collection of product objects in memory, you should call
> - getIteratorByQuery() which returns an Iterator instead of a
> Collection.
> + <code>getIteratorByQuery()</code> which returns an Iterator
instead
> + of a <code>Collection</code>.
> </p>
> <p>
> This method is extremely useful if you write applications that
> @@ -313,7 +320,7 @@
> all at once, they are created on an "as needed" basis as you
> iterate through the result. Instances of persistent objects
which
> are no longer referenced by the application can be reclaimed by
> - the garbage collector. Using this method the code will resemble
> + the garbage collector. Using this method the code would resemble
> the following:
> </p>
>
> @@ -321,10 +328,9 @@
> public void apply()
> {
> System.out.println("The list of available products:");
> +
> // build a query that select all objects of Class Product,
> - // without any further criteria according to ODMG
> - // the Collection containing all
> - // instances of a persistent class is called "Extent"
> + // without any further criteria.
> Query query = new QueryByCriteria(Product.class, null);
> try
> {
> @@ -345,21 +351,20 @@
>
> <p>
> For further information you may have a look at the
> - <A
> HREF="javadoc/ojb/broker/PersistenceBroker.html">PersistenceBroker
> JavaDoc</A>
> - and at the <A HREF="javadoc/ojb/broker/query/Query.html">Query
> JavaDoc</A>.
> + <a
> href="javadoc/ojb/broker/PersistenceBroker.html">PersistenceBroker
> JavaDoc</a>
> + and at the <a href="javadoc/ojb/broker/query/Query.html">Query
> JavaDoc</a>.
> </p>
> </subsection>
>
>
> <subsection name="Storing objects">
> -<p>Now we'll have a look at the use case UCEnterNewProduct. It works
> -as follows: first create a new object, then ask the user for the new
> -product's data (productname, price and available stock). These data
> -is stored in the new objects attributes. Then we must store the newly
> -created object in the persistent store. We can use the method
> -<code>PersistenceBroker.store(Object obj)</code>
> -for this task.
> -</p>
> + <p>Now we will have a look at the use case
> <code>UCEnterNewProduct</code>. It works
> + as follows: first create a new object, then ask the user for the
> new
> + product's data (product name, price and available stock). This
data
> + is stored in the new object's attributes. We then must store the
> newly
> + created object in the persistent store. We can use the method
> + <code>PersistenceBroker.store(Object obj)</code> for this task.
> + </p>
> <source><![CDATA[
> public void apply()
> {
> @@ -395,12 +400,12 @@
> ]]></source>
>
> <p>
> - Maybe you have noticed that there has not been any assignment to
> - newProduct._id, the primary key attribute. On storing of
newProduct
> + Maybe you have noticed that there has not been an assignment to
> + <code>newProduct._id</code>, the primary-key attribute. upon
> storing <code>newProduct</code>
> OJB detects that the attribute is not properly set and assigns a
> unique id. This automatic assignment of unique Ids for the
> Attribute
> - _id has been eplicitly declared in the XML-Repository (see
section
> - '<A HREF="#def_or">Defining the Object/Relational Mapping</A>'
> below).
> + <code>_id</code> has been eplicitly declared in the XML
Repository
> (see section
> + <a href="#def_or">Defining the Object/Relational Mapping</a>).
> </p>
>
> </subsection>
> @@ -408,7 +413,7 @@
>
> <p>
> When a user wants to edit a product ( by selecting item #2 from
the
> - menu ), a user must first enter the "id" of the product to be
> + menu ), the user must first enter the "id" of the product to be
> edited. Since the application does not maintain a list of
product
> objects, the system must first retrieve a product from persistent
> storage via the PersistenceBroker.
> @@ -416,17 +421,17 @@
>
> <p>
> Selecting an object from the PersistenceBroker is simple - we
must
> - first create a QueryByCriteria object. A QueryByCriteria object
is
> + first create a QueryByCriteria object. A QueryByCriteria object is
> created with a new Product object that contains an "id" property
> - which has been populated with the id the user supplied. You will
> + which has been populated with the id the user supplied. You will
> notice that all of the other properties of the Product object
> remain unpopulated. We have essentially defined a <b>filter</b>
by
> populating only the "productId" property - our query will
retrieve
> only
> - the product that has this productId. Instead of passing an object
> to the
> + the product that has this productId. Instead of passing an object
> to the
> query constructor, we could have passed a Class, and a Criteria
> object.
> Constructing a Criteria object directly allows you
> to specify an arbitrarily complex collection of query criteria
such
> as "productId"
> - must be greater than 2 and less than 5. A complex query is
> demonstrated later in this
> + must be greater than 2 and less than 5. A complex query is
> demonstrated later in this
> tutorial.
> </p>
>
> @@ -447,7 +452,7 @@
>
> // We do not have a reference to the selected Product.
> // So first we have to lookup the object,
> - // we do this by a query by example (QBE):
> + // we do this by a query by criteria
> // 1. build an example object with matching primary key values:
> Product example = new Product();
> example.setId(id);
> @@ -493,9 +498,9 @@
>
> <subsection name="Deleting Objects">
> <p>
> - The UseCase UCDeleteProduct allows the user to select one of the
> + The UseCase <code>UCDeleteProduct</code> allows the user to
select
> one of the
> existing products and to delete it from the persistent storage.
The
> - user enters the products unique id and the broker tries to lookup
> the
> + user enters the product's unique id and the PersistenceBroker
> tries to lookup the
> respective object. This lookup is necessary as our application
does
> not hold a list of all products. The found object must then be
> deleted by the broker. Here is the code:
> @@ -509,7 +514,7 @@
>
> // We do not have a reference to the selected Product.
> // So first we have to lookup the object,
> - // we do this by a query by example (QBE):
> + // we do this by a query by Criteria
> // 1. build an example object with matching primary key values:
> Product example = new Product();
> example.setId(id);
> @@ -519,7 +524,7 @@
> {
> // start broker transaction
> broker.beginTransaction();
> - // lookup the product specified by the QBE
> + // lookup the product specified by the Criteria
> Product toBeDeleted = (Product)
broker.getObjectByQuery(query);
> // now ask broker to delete the object
> broker.delete(toBeDeleted);
> @@ -546,14 +551,14 @@
> <source><![CDATA[
> // build filter criteria:
> Criteria criteria = new Criteria();
> - criteria.addEqualTo(_id, new Integer(id));
> + criteria.addEqualTo("_id", new Integer(id));
> // build a query for the class Product with these filter
criteria:
> Query query = new QueryByCriteria(Product.class, criteria);
> ...
> ]]></source>
>
> <p>
> - An arbitrary number of criteria can be added to produce very
complex
> + An arbitrary number of criteria can be added in order to produce
> very complex
> queries. The following code demonstrates a more complex use of
the
> Criteria
> object, one that is not present in this tutorial application.
This
> code
> retrieves all products which are priced less than 5.40 (USD, Yen,
> Euros, etc.)
> @@ -581,7 +586,7 @@
>
> <p>
> Now you are familiar with the basic functionalities of the OJB
> - PersistenceBroker. To learn more you might consider implementing
> the
> + PersistenceBroker API. To learn more you might consider
> implementing the
> following additional use cases:
> <ol>
> <li>
> @@ -601,7 +606,7 @@
>
> <section name="Defining the Object/Relational Mapping">
>
> -<A NAME="def_or"></A>
> +<a name="def_or"></a>
> <p>
> After looking at the code of the tutorial application and at the
> sample database (<code>bin\build browse-db</code> will
> @@ -614,17 +619,17 @@
> </p>
> <p>
> The answer is: It's done in the OJB Metadata Repository. This
> - Repository consists of a set of classes describing the O/R
mapping
> - (have a look at the package
> <B><code>org.apache.ojb.broker.metadata</code></B>).
> + repository consists of a set of classes describing the O/R
mapping
> + (have a look at the package
> <b><code>org.apache.ojb.broker.metadata</code></b>).
> The repository consists of ordinary Java objects that can be
> created
> and modified at runtime. This brings a lot flexibility for
special
> situations where it is neccessary to change the mapping
> dynamically.Keeping the mapping dynamic has several advantages:
> </p>
> <ul>
> - <li>No preprocessing of Java sourcecode, no fix compiled
persistence
> classes</li>
> + <li>No preprocessing of Java sourcecode, no modifying compiled
> classes</li>
> <li>
> - Mapping can be inspected and changed at runtime, allows maximum
> flexibility
> + Mapping can be inspected and changed at runtime, allowing maximum
> flexibility
> in changing persistence behaviour or in building your own
> persistence layers
> on top of OJB.
> </li>
> @@ -633,16 +638,15 @@
> But it has also at least one disadvantage: Performance. Due to
the
> dynamic approach OJB uses either Java Reflection or JavaBeans
> compliant
> access to inspect and modify business objects.
> - We took great care to reduce the dynamic access overhead to a
> minimum.
> + OJB takes great care to reduce the dynamic access overhead to a
> minimum.
> </p>
> <p>
> - In the following sections I will show how the O/R mapping is
> - defined for the tutorial application.
> + The following sections dmeonstrate the O/R mapping for the
> tutorial application.
> </p>
> <subsection name="A Persistent Class: Product">
> <p>
> - There is only one persistent class in our tutorial application,
> - the class <code>Product</code>. Here it's definition:
> + There is only one persistent class in the tutorial application,
> + the class <code>Product</code>. Here its' definition:
> </p>
>
> <source><![CDATA[
> @@ -664,15 +668,15 @@
> ]]></source>
>
> <p>
> - I ommited the method definitions, as they are not relevant for
the
> + The method definitions have been ommitted, as they are not
> relevant for the
> O/R mapping process.
> </p>
> </subsection>
>
> <subsection name="The Product Database Table">
> <p>
> - Now we take a look at a corresponding table definition, in SQL
DDL
> - (I give the instantDB syntax here, the syntax may vary slightly
for
> + Now, take a look at a corresponding table definition, in SQL DDL
> + (The InstantDB syntax is given here, the syntax may vary slightly
> for
> your favourite RDBMS):
> </p>
>
> @@ -686,17 +690,14 @@
> ]]></source>
>
> <p>
> - You will notice that I added a primary key column
<code>ID</code>.
> + Notice that the primary key column <code>ID</code>.
> This is an <code>artificial attribute</code> as it not derived
from
> the domain model. To use such an artificial key instead of a
> compound
> key of domain attributes is recommended but not mandatory for
O/R
> mappings. If you are using such artificial keys you have to
modify
> the original class layout slightly and include a corresponding
> - attribute. OJB requires that <B>all</B> primary key columns of a
> - table are reflected in attributes in the coresponding class. This
> is
> - one of the very few <code>intrusions</code> of the persistence
> layer
> - into your business code, because these attributes are not
> necessarily
> - part of the OOD model.
> + attribute, or make use an <a
> href="howto-use-anonymous-keys.html">anonymous key</a>.
> + This example allows the primary key to intrude into the object
> model.
> </p>
> <p>
> So we must change our initial class definition slightly to match
> @@ -729,7 +730,7 @@
> </p>
> <p>
> <b>There is one important exception:</b> persistent capable
> classes <B>must</B>
> - provide a public no-argument constructor.
> + provide a no-argument constructor, but it may be private.
> <!--Implementing a constructor that
> initializes all persistent attributes is recommended for
> performance
> reasons but not required. OJB will print out warnings when such
a
> @@ -766,33 +767,41 @@
> <!ENTITY junit SYSTEM "repository_junit.xml">
> <!ENTITY internal SYSTEM "repository_internal.xml">
> ]>
> +<!DOCTYPE descriptor-repository PUBLIC
> + "-//Apache Software Foundation//DTD OJB Repository//EN"
> + "repository.dtd"
> +[
> +<!ENTITY database SYSTEM "repository_database.xml">
> +<!ENTITY internal SYSTEM "repository_internal.xml">
> +<!ENTITY junit SYSTEM "repository_junit.xml">
> +<!ENTITY user SYSTEM "repository_user.xml">
> +<!ENTITY ejb SYSTEM "repository_ejb.xml">
> +<!ENTITY jdo SYSTEM "repository_jdo.xml">
> +]>
> +
> +
> +<descriptor-repository version="1.0"
> isolation-level="read-uncommitted">
>
> + <!-- include all used database connections -->
> + &database;
>
> -<descriptor-repository version="0.9.1"
> - isolation-level="read-uncommitted">
> -<!-- The Default JDBC Connection. If a class-descriptor does not
> - specify its own JDBC Connection,
> - the Connection specified here will be used. -->
> -
> - <jdbc-connection-descriptor
> - platform="Hsqldb"
> - jdbc-level="2.0"
> - driver="org.hsqldb.jdbcDriver"
> - protocol="jdbc"
> - subprotocol="hsqldb"
> - dbalias="/samples/hsql/OJB"
> - username="sa"
> - password=""
> - />
> + <!-- include ojb internal mappings here -->
> + &internal;
> +
> + <!-- include mappings for JUnit tests -->
> + <!-- This could be removed (with <!ENTITY entry),
> + if junit test suite was not used
> + -->
> + &junit;
>
> <!-- include user defined mappings here -->
> &user;
>
> - <!-- include mappings for JUnit tests and sample apps here -->
> - &junit;
> + <!-- include mappings for the EJB-examples -->
> + <!-- &ejb; -->
>
> - <!-- include ojb internal mappings here -->
> - &internal;
> + <!-- include mappings for the JDO tutorials -->
> + &jdo;
>
> </descriptor-repository>
> ]]></source>
> @@ -957,9 +966,6 @@
> <p>
> I hope you found this tutorial helpful. Any comments are welcome.
> </p>
> -
> -
> -
> </section>
>
> </body>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-dev-help@db.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org
Re: [PATCH] tutorial1.xml updates
Posted by Brian McCallister <mc...@forthillcompany.com>.
Argh, the attachement problem.
Patch inlined:
--------------------------------
Index: xdocs/tutorial1.xml
===================================================================
RCS file: /home/cvspublic/db-ojb/xdocs/tutorial1.xml,v
retrieving revision 1.20
diff -u -r1.20 tutorial1.xml
--- xdocs/tutorial1.xml 20 Jul 2003 20:37:25 -0000 1.20
+++ xdocs/tutorial1.xml 7 Aug 2003 18:00:29 -0000
@@ -17,14 +17,14 @@
(OJB) object/relational mapping in a simple application scenario.
The
tutorial application implements a product catalog database with
some
basic use cases. The source code for the tutorial application is
- shipped with the OJB source distribution and resides in the package
- <B><code>org.apache.ojb.tutorial1</code></B>.
+ shipped with the OJB source distribution and resides in the
+ <B><code>src/test/org/apache/ojb/tutorial1/</code></B> directory.
</p>
<p>
This document explains the architecture of a simple application
which
- uses the ObJectRelationalBridge API (PersistenceBroker) to
+ uses the ObJectRelationalBridge PersistenceBroker API to
implement five use cases which include persistence operations
(retrieval,
- storage, deletion of objects). This document will also demonstrate
how a
+ storage, and deletion of objects). This document will also
demonstrate how a
simple persistence object <code>Product</code> is mapped to a
table in
a relational database.
</p>
@@ -32,7 +32,7 @@
<subsection name="The Tutorial Application">
<p>
- The sample application is a console based data entry application -
+ The sample application is a console based data entry application --
a program to manipulate a product catalog database with five simple
use cases:
</p>
@@ -40,7 +40,7 @@
<ol>
<li>
<b>List all Products</b> -
- display all products from the persistent store.
+ display all products from the persistent store
</li>
<li>
<b>Enter a new Product</b> -
@@ -77,8 +77,8 @@
OJB. This is accomplished via Ant build scripts which are executed
by a script in the "bin" directory of the OJB distribution. (Note:
This tutorial assumes that you have already downloaded the OJB
- source distribution.) Note: There is no need to configure a
- database in order to run these applications. The tutorial
applications
+ source distribution.) There is no need to configure a
+ database in order to run these applications. The tutorial
applications
ship with HSQLDB integration, all you need to do is run the
prepare-tutorials Ant target.
</p>
@@ -136,7 +136,7 @@
</p>
<p>
The <code>Application.run()</code> method runs a main event loop.
The
- program waits for user input in
<code>Application.selectUserCase()</code>.
+ program waits for user input in
<code>Application.selectUseCase()</code>.
Once a UseCase is selected, it is executed via the
<code>UseCase.apply()</code> method. This UseCase class is a
simple
implementation of the well-known Command design pattern.</p>
@@ -207,21 +207,26 @@
database access.
</p>
<p>
- You will find the source for the PersistenceBroker API in the
- package <code>org.apache.ojb.broker</code>.
- <A HREF="javadoc/org/apache/ojb/broker/package-summary.html">The
- JavaDoc is here</A>. The key component in this package is the
- interface <code>PersistenceBroker</code>. It
- provides methods for retrieval, storage and deletion of objects. To
- use it in your application you must know how to retrieve a Broker
- instance, how to configure its O/R mapping repository and how to
use
- the available functionsI.
+ You will find the source for the <a
+
href="javadoc/org/apache/ojb/broker/package-
summary.html">PersistenceBroker
+ API</a> in the package <code>org.apache.ojb.broker</code>. The key
+ component in this package is the interface
<code>PersistenceBroker</code>.
+ It provides methods for retrieval, storage, and deletion of
objects. To use
+ it in your application you must know how to retrieve a
+ <code>PersistenceBroker</code> instance, how to configure its O/R
mapping
+ repository and how to use the available functions.
</p>
<subsection name="Obtaining a Broker Instance">
<p>
- How do we obtain a Broker instance? Take a look at the public
constructor
- of the Application class to find the answer to this question.
+ The <code>Application</code> class's public constructor
demonstrates how to
+ obtain a <code>PersistenceBroker</code> instance:
+ <!--
+ Is this the best way to demonstrate use of a Broker? Broker's
are
+ pooled, but this application uses the same one forever. As
this is
+ a single threaded application it doesn't hurt, but an awful
lot of people
+ are using PB's in servlet based, multi-threaded, development
+ -->
</p>
<source><![CDATA[
public Application()
@@ -246,24 +251,26 @@
]]></source>
<p>
The PersistenceBrokerFactory creates an instance of
PersistenceBroker
- using the resource ./repository.xml as a mapping repository (more
- details on this repository in the <A HREF="#def_or">section on the
- Object/Relational mapping</A>. The PersistenceBroker instance is
+ using the resource <code>repository.xml</code> as a mapping
repository (more
+ details on this repository in the <a href="#def_or">section on the
+ Object/Relational mapping</a>. The PersistenceBroker instance is
passed to the constructor of the four UseCase objects which
store this PersistenceBroker instance as a protected member
variable.
</p>
</subsection>
<subsection name="Retrieving Collections and Iterators">
<p>
- The next thing we need to know is how to use this broker instance
to implement
- our persistence operations. In this use case, we have to retrieve a
- collection containing all product entries from the database. To
- retrieve a collection containing objects matching some criteria we
can use
- <code>PersistenceBroker.getCollectionByQuery(Query query)</code>.
- Where <code>Query</code> is a class that allows to specify
criteria like
- price > 100 or userId == 3. In our case we want to select
<I>all</I>
- of the persistence objects stored in the Product table. We need
<b>no</b>
- (or <i>null</i>) filtering criteria.
+ The next thing we need to know is how to use this broker instance
to
+ implement our persistence operations. In this use case, we have to
retrieve
+ a collection containing all product entries from the database. To
retrieve a
+ collection containing objects matching some criteria we can use
+ <code>PersistenceBroker.getCollectionByQuery(Query query)</code>.
Where
+ <code>Query</code> is a class that allows specification of
criteria such as
+ <code>price > 100</code> or <code>userId == 3</code>. In this
case we
+ want to select <i>all</i> of the persistence objects stored in the
+ <code>Product</code> table. We need <b>no</b> (or <b>null</b>)
filtering
+ criteria. According to the ODMG the Collection containing all
instances of
+ a persistent class is called an <b>Extent</b>.
</p>
<p>
Here is the code of the
<code>UCListAllProducts.apply()</code>method:
@@ -273,10 +280,9 @@
public void apply()
{
System.out.println("The list of available products:");
- // build a query that selects all objects of Class Product,
- // without any further criteria according to ODMG the
- // Collection containing all instances of a
- // persistent class is called "Extent"
+
+ // build a query which selects all objects of class Product,
+ // without any further criteria
Query query = new QueryByCriteria(Product.class, null);
try
{
@@ -305,7 +311,8 @@
provides a more efficient mechanism for iterating through all the
available products. If your application does not need to maintain a
collection of product objects in memory, you should call
- getIteratorByQuery() which returns an Iterator instead of a
Collection.
+ <code>getIteratorByQuery()</code> which returns an Iterator instead
+ of a <code>Collection</code>.
</p>
<p>
This method is extremely useful if you write applications that
@@ -313,7 +320,7 @@
all at once, they are created on an "as needed" basis as you
iterate through the result. Instances of persistent objects which
are no longer referenced by the application can be reclaimed by
- the garbage collector. Using this method the code will resemble
+ the garbage collector. Using this method the code would resemble
the following:
</p>
@@ -321,10 +328,9 @@
public void apply()
{
System.out.println("The list of available products:");
+
// build a query that select all objects of Class Product,
- // without any further criteria according to ODMG
- // the Collection containing all
- // instances of a persistent class is called "Extent"
+ // without any further criteria.
Query query = new QueryByCriteria(Product.class, null);
try
{
@@ -345,21 +351,20 @@
<p>
For further information you may have a look at the
- <A
HREF="javadoc/ojb/broker/PersistenceBroker.html">PersistenceBroker
JavaDoc</A>
- and at the <A HREF="javadoc/ojb/broker/query/Query.html">Query
JavaDoc</A>.
+ <a
href="javadoc/ojb/broker/PersistenceBroker.html">PersistenceBroker
JavaDoc</a>
+ and at the <a href="javadoc/ojb/broker/query/Query.html">Query
JavaDoc</a>.
</p>
</subsection>
<subsection name="Storing objects">
-<p>Now we'll have a look at the use case UCEnterNewProduct. It works
-as follows: first create a new object, then ask the user for the new
-product's data (productname, price and available stock). These data
-is stored in the new objects attributes. Then we must store the newly
-created object in the persistent store. We can use the method
-<code>PersistenceBroker.store(Object obj)</code>
-for this task.
-</p>
+ <p>Now we will have a look at the use case
<code>UCEnterNewProduct</code>. It works
+ as follows: first create a new object, then ask the user for the
new
+ product's data (product name, price and available stock). This data
+ is stored in the new object's attributes. We then must store the
newly
+ created object in the persistent store. We can use the method
+ <code>PersistenceBroker.store(Object obj)</code> for this task.
+ </p>
<source><![CDATA[
public void apply()
{
@@ -395,12 +400,12 @@
]]></source>
<p>
- Maybe you have noticed that there has not been any assignment to
- newProduct._id, the primary key attribute. On storing of newProduct
+ Maybe you have noticed that there has not been an assignment to
+ <code>newProduct._id</code>, the primary-key attribute. upon
storing <code>newProduct</code>
OJB detects that the attribute is not properly set and assigns a
unique id. This automatic assignment of unique Ids for the
Attribute
- _id has been eplicitly declared in the XML-Repository (see section
- '<A HREF="#def_or">Defining the Object/Relational Mapping</A>'
below).
+ <code>_id</code> has been eplicitly declared in the XML Repository
(see section
+ <a href="#def_or">Defining the Object/Relational Mapping</a>).
</p>
</subsection>
@@ -408,7 +413,7 @@
<p>
When a user wants to edit a product ( by selecting item #2 from the
- menu ), a user must first enter the "id" of the product to be
+ menu ), the user must first enter the "id" of the product to be
edited. Since the application does not maintain a list of product
objects, the system must first retrieve a product from persistent
storage via the PersistenceBroker.
@@ -416,17 +421,17 @@
<p>
Selecting an object from the PersistenceBroker is simple - we must
- first create a QueryByCriteria object. A QueryByCriteria object is
+ first create a QueryByCriteria object. A QueryByCriteria object is
created with a new Product object that contains an "id" property
- which has been populated with the id the user supplied. You will
+ which has been populated with the id the user supplied. You will
notice that all of the other properties of the Product object
remain unpopulated. We have essentially defined a <b>filter</b> by
populating only the "productId" property - our query will retrieve
only
- the product that has this productId. Instead of passing an object
to the
+ the product that has this productId. Instead of passing an object
to the
query constructor, we could have passed a Class, and a Criteria
object.
Constructing a Criteria object directly allows you
to specify an arbitrarily complex collection of query criteria such
as "productId"
- must be greater than 2 and less than 5. A complex query is
demonstrated later in this
+ must be greater than 2 and less than 5. A complex query is
demonstrated later in this
tutorial.
</p>
@@ -447,7 +452,7 @@
// We do not have a reference to the selected Product.
// So first we have to lookup the object,
- // we do this by a query by example (QBE):
+ // we do this by a query by criteria
// 1. build an example object with matching primary key values:
Product example = new Product();
example.setId(id);
@@ -493,9 +498,9 @@
<subsection name="Deleting Objects">
<p>
- The UseCase UCDeleteProduct allows the user to select one of the
+ The UseCase <code>UCDeleteProduct</code> allows the user to select
one of the
existing products and to delete it from the persistent storage. The
- user enters the products unique id and the broker tries to lookup
the
+ user enters the product's unique id and the PersistenceBroker
tries to lookup the
respective object. This lookup is necessary as our application does
not hold a list of all products. The found object must then be
deleted by the broker. Here is the code:
@@ -509,7 +514,7 @@
// We do not have a reference to the selected Product.
// So first we have to lookup the object,
- // we do this by a query by example (QBE):
+ // we do this by a query by Criteria
// 1. build an example object with matching primary key values:
Product example = new Product();
example.setId(id);
@@ -519,7 +524,7 @@
{
// start broker transaction
broker.beginTransaction();
- // lookup the product specified by the QBE
+ // lookup the product specified by the Criteria
Product toBeDeleted = (Product) broker.getObjectByQuery(query);
// now ask broker to delete the object
broker.delete(toBeDeleted);
@@ -546,14 +551,14 @@
<source><![CDATA[
// build filter criteria:
Criteria criteria = new Criteria();
- criteria.addEqualTo(_id, new Integer(id));
+ criteria.addEqualTo("_id", new Integer(id));
// build a query for the class Product with these filter criteria:
Query query = new QueryByCriteria(Product.class, criteria);
...
]]></source>
<p>
- An arbitrary number of criteria can be added to produce very complex
+ An arbitrary number of criteria can be added in order to produce
very complex
queries. The following code demonstrates a more complex use of the
Criteria
object, one that is not present in this tutorial application. This
code
retrieves all products which are priced less than 5.40 (USD, Yen,
Euros, etc.)
@@ -581,7 +586,7 @@
<p>
Now you are familiar with the basic functionalities of the OJB
- PersistenceBroker. To learn more you might consider implementing
the
+ PersistenceBroker API. To learn more you might consider
implementing the
following additional use cases:
<ol>
<li>
@@ -601,7 +606,7 @@
<section name="Defining the Object/Relational Mapping">
-<A NAME="def_or"></A>
+<a name="def_or"></a>
<p>
After looking at the code of the tutorial application and at the
sample database (<code>bin\build browse-db</code> will
@@ -614,17 +619,17 @@
</p>
<p>
The answer is: It's done in the OJB Metadata Repository. This
- Repository consists of a set of classes describing the O/R mapping
- (have a look at the package
<B><code>org.apache.ojb.broker.metadata</code></B>).
+ repository consists of a set of classes describing the O/R mapping
+ (have a look at the package
<b><code>org.apache.ojb.broker.metadata</code></b>).
The repository consists of ordinary Java objects that can be
created
and modified at runtime. This brings a lot flexibility for special
situations where it is neccessary to change the mapping
dynamically.Keeping the mapping dynamic has several advantages:
</p>
<ul>
- <li>No preprocessing of Java sourcecode, no fix compiled persistence
classes</li>
+ <li>No preprocessing of Java sourcecode, no modifying compiled
classes</li>
<li>
- Mapping can be inspected and changed at runtime, allows maximum
flexibility
+ Mapping can be inspected and changed at runtime, allowing maximum
flexibility
in changing persistence behaviour or in building your own
persistence layers
on top of OJB.
</li>
@@ -633,16 +638,15 @@
But it has also at least one disadvantage: Performance. Due to the
dynamic approach OJB uses either Java Reflection or JavaBeans
compliant
access to inspect and modify business objects.
- We took great care to reduce the dynamic access overhead to a
minimum.
+ OJB takes great care to reduce the dynamic access overhead to a
minimum.
</p>
<p>
- In the following sections I will show how the O/R mapping is
- defined for the tutorial application.
+ The following sections dmeonstrate the O/R mapping for the
tutorial application.
</p>
<subsection name="A Persistent Class: Product">
<p>
- There is only one persistent class in our tutorial application,
- the class <code>Product</code>. Here it's definition:
+ There is only one persistent class in the tutorial application,
+ the class <code>Product</code>. Here its' definition:
</p>
<source><![CDATA[
@@ -664,15 +668,15 @@
]]></source>
<p>
- I ommited the method definitions, as they are not relevant for the
+ The method definitions have been ommitted, as they are not
relevant for the
O/R mapping process.
</p>
</subsection>
<subsection name="The Product Database Table">
<p>
- Now we take a look at a corresponding table definition, in SQL DDL
- (I give the instantDB syntax here, the syntax may vary slightly for
+ Now, take a look at a corresponding table definition, in SQL DDL
+ (The InstantDB syntax is given here, the syntax may vary slightly
for
your favourite RDBMS):
</p>
@@ -686,17 +690,14 @@
]]></source>
<p>
- You will notice that I added a primary key column <code>ID</code>.
+ Notice that the primary key column <code>ID</code>.
This is an <code>artificial attribute</code> as it not derived from
the domain model. To use such an artificial key instead of a
compound
key of domain attributes is recommended but not mandatory for O/R
mappings. If you are using such artificial keys you have to modify
the original class layout slightly and include a corresponding
- attribute. OJB requires that <B>all</B> primary key columns of a
- table are reflected in attributes in the coresponding class. This
is
- one of the very few <code>intrusions</code> of the persistence
layer
- into your business code, because these attributes are not
necessarily
- part of the OOD model.
+ attribute, or make use an <a
href="howto-use-anonymous-keys.html">anonymous key</a>.
+ This example allows the primary key to intrude into the object
model.
</p>
<p>
So we must change our initial class definition slightly to match
@@ -729,7 +730,7 @@
</p>
<p>
<b>There is one important exception:</b> persistent capable
classes <B>must</B>
- provide a public no-argument constructor.
+ provide a no-argument constructor, but it may be private.
<!--Implementing a constructor that
initializes all persistent attributes is recommended for
performance
reasons but not required. OJB will print out warnings when such a
@@ -766,33 +767,41 @@
<!ENTITY junit SYSTEM "repository_junit.xml">
<!ENTITY internal SYSTEM "repository_internal.xml">
]>
+<!DOCTYPE descriptor-repository PUBLIC
+ "-//Apache Software Foundation//DTD OJB Repository//EN"
+ "repository.dtd"
+[
+<!ENTITY database SYSTEM "repository_database.xml">
+<!ENTITY internal SYSTEM "repository_internal.xml">
+<!ENTITY junit SYSTEM "repository_junit.xml">
+<!ENTITY user SYSTEM "repository_user.xml">
+<!ENTITY ejb SYSTEM "repository_ejb.xml">
+<!ENTITY jdo SYSTEM "repository_jdo.xml">
+]>
+
+
+<descriptor-repository version="1.0"
isolation-level="read-uncommitted">
+ <!-- include all used database connections -->
+ &database;
-<descriptor-repository version="0.9.1"
- isolation-level="read-uncommitted">
-<!-- The Default JDBC Connection. If a class-descriptor does not
- specify its own JDBC Connection,
- the Connection specified here will be used. -->
-
- <jdbc-connection-descriptor
- platform="Hsqldb"
- jdbc-level="2.0"
- driver="org.hsqldb.jdbcDriver"
- protocol="jdbc"
- subprotocol="hsqldb"
- dbalias="/samples/hsql/OJB"
- username="sa"
- password=""
- />
+ <!-- include ojb internal mappings here -->
+ &internal;
+
+ <!-- include mappings for JUnit tests -->
+ <!-- This could be removed (with <!ENTITY entry),
+ if junit test suite was not used
+ -->
+ &junit;
<!-- include user defined mappings here -->
&user;
- <!-- include mappings for JUnit tests and sample apps here -->
- &junit;
+ <!-- include mappings for the EJB-examples -->
+ <!-- &ejb; -->
- <!-- include ojb internal mappings here -->
- &internal;
+ <!-- include mappings for the JDO tutorials -->
+ &jdo;
</descriptor-repository>
]]></source>
@@ -957,9 +966,6 @@
<p>
I hope you found this tutorial helpful. Any comments are welcome.
</p>
-
-
-
</section>
</body>
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org