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 ar...@apache.org on 2005/12/16 21:55:49 UTC
cvs commit: db-ojb/src/doc/forrest/src/documentation/content/xdocs site.xml
arminw 2005/12/16 12:55:49
Modified: src/doc/forrest/src/documentation/content/xdocs/docu/guides
Tag: OJB_1_0_RELEASE advanced-technique.xml
src/doc/forrest/src/documentation/content/xdocs Tag:
OJB_1_0_RELEASE site.xml
Log:
update docs
Revision Changes Path
No revision
No revision
1.1.2.7 +153 -132 db-ojb/src/doc/forrest/src/documentation/content/xdocs/docu/guides/advanced-technique.xml
Index: advanced-technique.xml
===================================================================
RCS file: /home/cvs/db-ojb/src/doc/forrest/src/documentation/content/xdocs/docu/guides/advanced-technique.xml,v
retrieving revision 1.1.2.6
retrieving revision 1.1.2.7
diff -u -r1.1.2.6 -r1.1.2.7
--- advanced-technique.xml 14 Dec 2005 01:19:19 -0000 1.1.2.6
+++ advanced-technique.xml 16 Dec 2005 20:55:48 -0000 1.1.2.7
@@ -28,49 +28,42 @@
</header>
<body>
- <section>
- <title>Introduction</title>
- <p>
- </p>
- </section>
-
<anchor id="polymorphism"/>
<section>
<title>Extents and Polymorphism</title>
<p>
Working with inheritance hierarchies is a common task in object
oriented design and programming. Of course, any serious Java O/R tool
- must support inheritance and interfaces for persistent classes. To
- demonstrate we will look at some of the JUnit TestSuite classes.
+ must support inheritance and interfaces for persistent classes.
+ There are many example classes for polymorphism in
+ <a href="site:test-suite">OJB's JUnit TestSuite</a>.
</p>
<p>
- There is a primary interface "InterfaceArticle". This
- interface is implemented by "Article" and "CdArticle".
- There is also a class "BookArticle" derived from "Article".
+ To demonstrate/explain <em>Extents</em> and <em>Polymorphism</em> we will look at
+ a simple class hierarchy:
+ <br/>
+ There is a primary interface <code>InterfaceArticle</code>. This
+ interface is implemented by <code>Article</code> and <code>CdArticle</code>.
+ There is also a class <code>BookArticle</code> derived from <code>Article</code>.
(See the following class diagram for details)
</p>
+ <anchor id="example-hierarchy"/>
<p>
<img src="images/polymorphism.gif" alt="polymorphism.gif"/>
</p>
<section>
<title>Polymorphism</title>
<p>
- OJB allows us to use interfaces, abstract, or concrete base classes in
- queries, or in type definitions of reference attributes. A Query
- against the interface
- <code>InterfaceArticle</code>
- must not only return objects of type
- <code>Article</code>
- but also of
- <code>CdArticle</code> and
- <code>BookArticle</code>! The following
- test method searches for all objects implementing
- <code>InterfaceArticle</code>
- with an
- <code>articleName</code> equal to "Hamlet". The Collection is
- filled with one matching
- <code>BookArticle
- </code> object.
+ OJB allows us to use interfaces, abstract or concrete base classes in
+ queries, or in <a href="site:basic-technique"> type definitions of reference attributes</a>.
+ A Query against the interface <code>InterfaceArticle</code> must not only return objects of type
+ <code>Article</code> but also of <code>CdArticle</code> and <code>BookArticle</code>!
+ <br/>
+ The following <a href="#example-hierarchy">example</a> method searches for all objects implementing
+ <code>InterfaceArticle</code> with an <em>articleName</em> equal to
+ <em>Hamlet</em> (provided that the object mapping is correct, details will described later).
+ The Collection is e.g filled with one matching
+ <code>BookArticle</code> object.
</p>
<source><![CDATA[
public void testCollectionByQuery() throws Exception
@@ -80,18 +73,14 @@
Query q = QueryFactory.newQuery(InterfaceArticle.class, crit);
Collection result = broker.getCollectionByQuery(q);
-
- System.out.println(result);
-
- assertNotNull("should return at least one item", result);
- assertTrue("should return at least one item", result.size() > 0);
}]]></source>
-
<p>
- Of course it is also possible to define reference attributes of an
- interface or baseclass type. In all above examples Article has a
- reference attribute of type
- <code>InterfaceProductGroup</code>.
+ Of course it is also possible to define
+ <a href="site:basic-technique">reference attributes</a> of an
+ interface or baseclass type. The <a href="#example-hierarchy">example</a> class
+ <code>Article</code> has a reference attribute
+ (<a href="site:basic-technique/one-to-one">1:1 reference</a>) of type
+ <code>ProductGroup</code> and this can be a concrete/abstract class or interface.
</p>
</section>
@@ -100,10 +89,12 @@
<title>Extents</title>
<p>
The query in the last example returned just one object. Now,
- imagine a query against the InterfaceArticle interface with no selecting criteria.
- OJB returns all the objects implementing InterfaceArticle. I.e. All Articles, BookArticles and
- CdArticles. The following method prints out the collection of all
- InterfaceArticle objects:
+ imagine a query against the <code>InterfaceArticle</code> interface with no selecting criteria.
+ OJB returns all the objects implementing <code>InterfaceArticle</code>. E.g. all
+ <code>Article</code>, <code>BookArticle</code> and <code>CdArticles</code> objects.
+ <br/>
+ In the following <a href="#example-hierarchy">example</a> the method prints out the
+ collection of all <code>InterfaceArticle</code> objects:
</p>
<source><![CDATA[
public void testExtentByQuery() throws Exception
@@ -113,62 +104,67 @@
Collection result = broker.getCollectionByQuery(q);
System.out.println(
- "OJB proudly presents: The InterfaceArticle Extent\n" +result);
-
- assertNotNull("should return at least one item", result);
- assertTrue("should return at least one item", result.size() > 0);
+ "The InterfaceArticle Extent objects: " +result);
}]]></source>
- <p>
- The set of all instances of a class (whether living in memory or
- stored in a persistent medium) is called an
- <strong>Extent</strong> in ODMG and
- JDO terminology. OJB extends this notion slightly, as all objects
- implementing a given interface are regarded as members of the
- interface's extent.
- </p>
+ <note>
+ The set of all instances of a class (whether living in memory or stored in a
+ persistent medium) is called an <strong>Extent</strong> in ODMG and JDO terminology.
+ <br/>
+ OJB extends this notion slightly, as all objects which are subclasses of a concrete/abstract
+ base class or implementing a given interface can be regarded as members of the base class or
+ interface extent.
+ </note>
<p>In our class diagram we find:</p>
<ol>
- <li>two simple "one-class-only" extents, BookArticle and CdArticle.
+ <li>two simple <em>one-class-only</em> extents, BookArticle and CdArticle.
</li>
<li>A compound extent Article containing all Article and BookArticle instances.</li>
<li>An interface extent containing all Article, BookArticle and CdArticle instances.</li>
</ol>
<p>
- There is no extra coding necessary to define extents, but they
- have to be declared in the repository file. The classes from the
- above example require the following declarations:
+ There is no extra coding necessary to define <em>extents</em>, but they
+ have to be declared in the <a href="site:repository">metadata mapping file</a>.
+ The classes from the above <a href="#example-hierarchy">example</a> require
+ the following declarations:
</p>
<ol>
- <li>"one-class-only" extents require no declaration</li>
- <li>A declaration for the baseclass Article, defining which classes are subclasses of Article:</li>
- </ol>
-
+ <li><em>one-class-only</em> extents require no declaration</li>
+ <li>A declaration for the base class <code>Article</code>, defining
+ which classes are subclasses of Article:
<source><![CDATA[
<!-- Definitions for org.apache.ojb.ojb.broker.Article -->
- <class-descriptor
- class="org.apache.ojb.broker.Article"
- proxy="dynamic"
- table="Artikel"
- >
- <extent-class class-ref="org.apache.ojb.broker.BookArticle" />
- <extent-class class-ref="org.apache.ojb.broker.CdArticle" />
- ...
- </class-descriptor>]]></source>
- <ol>
- <li>A declaration for InterfaceArticle, defining which classes implement this interface:</li>
- </ol>
-
+<class-descriptor
+ class="org.apache.ojb.broker.Article"
+ proxy="false"
+ table="Artikel"
+ ...
+>
+ <extent-class class-ref="org.apache.ojb.broker.BookArticle" />
+...
+</class-descriptor>]]></source>
+ </li>
+ <li>A declaration for <code>InterfaceArticle</code>, defining which classes
+ implement this interface:
<source><![CDATA[
<!-- Definitions for org.apache.ojb.broker.InterfaceArticle -->
- <class-descriptor class="org.apache.ojb.broker.InterfaceArticle">
- <extent-class class-ref="org.apache.ojb.broker.Article" />
- <extent-class class-ref="org.apache.ojb.broker.BookArticle" />
- <extent-class class-ref="org.apache.ojb.broker.CdArticle" />
- </class-descriptor>]]></source>
+<class-descriptor class="org.apache.ojb.broker.InterfaceArticle">
+ <extent-class class-ref="org.apache.ojb.broker.Article" />
+ <extent-class class-ref="org.apache.ojb.broker.CdArticle" />
+ <!-- not needed to declare -->
+ <!--<extent-class class-ref="org.apache.ojb.broker.BookArticle" />-->
+</class-descriptor>]]></source>
+ <p>
+ No need to declare <code>BookArticle</code> here, because it's a declared sub
+ class of <code>Article</code>, so it's implicit declared by <code>Article</code>
+ extent.
+ </p>
+ </li>
+ </ol>
<p>
Why is it necessary to explicitely declare which classes implement an
- interface and which classes are derived from a baseclass? Of course
- it is quite simple in Java to check whether a class implements a
+ interface and which classes are derived from a base class?
+ <br/>
+ Of course it is quite simple in Java to check whether a class implements a
given interface or extends some other class. But sometimes it may not
be appropiate to treat special implementors (e.g. proxies) as proper
implementors.
@@ -181,25 +177,38 @@
<p>
In other cases it may be neccessary to treat
certain classes as implementors of an interface or as derived from a
- base even if they are not.
- </p>
- <p>
+ base even if they are not (we don't recommend to use this feature it's bad design, but if
+ you don't have an alternative...).
+ <br/>
As an example, you will find that the
- ClassDescriptor for class org.apache.ojb.broker.Article in the
- repository.xml contains an entry declaring class CdArticle as a
- derived class:
+ <a href="site:repository/class-descriptor">ClassDescriptor</a> of abstract test class
+ <code>org.apache.ojb.broker.CollectionTest$BookShelfItem</code> in the
+ <a href="site:test-suite">OJB's Test Suite</a> contains an
+ entry declaring class <code>org.apache.ojb.broker.CollectionTest$Candie</code> as a derived class:
</p>
<source><![CDATA[
-<!-- Definitions for org.apache.ojb.ojb.broker.Article -->
- <class-descriptor
- class="org.apache.ojb.broker.Article"
- proxy="dynamic"
- table="Artikel"
- >
- <extent-class class-ref="org.apache.ojb.broker.BookArticle" />
- <extent-class class-ref="org.apache.ojb.broker.CdArticle" />
- ...
- </class-descriptor>]]></source>
+<class-descriptor class="org.apache.ojb.broker.CollectionTest$BookShelfItem">
+ <extent-class class-ref="org.apache.ojb.broker.CollectionTest$Book"/>
+ <extent-class class-ref="org.apache.ojb.broker.CollectionTest$DVD"/>
+ <!-- This class isn't a subclass of Book or DVD or a implementation of
+ BookShelfItem, anyway it's possible to declare it as extent (but not recommended) -->
+ <extent-class class-ref="org.apache.ojb.broker.CollectionTest$Candie"/>
+</class-descriptor>]]></source>
+ </section>
+
+ <anchor id="performance-tip"/>
+ <section>
+ <title>Performance Tip</title>
+ <p>
+ When using <em>extents</em> OJB will produce some overhead for each declared
+ extent (e.g. execute a separate select-query for each extent or using complex table joins).
+ <br/>
+ Thus it's important to avoid unnecessary <em>extent</em> declarations. If in the above
+ <a href="#example-hierarchy">example</a> class <code>InterfaceArticle</code> is never
+ used in queries, don't declare the extents for the implementing classes
+ (<code>Article</code>, <code>CdArticle</code>). It's always possible to add additional
+ <em>extents</em> in <a href="site:repository">mapping files</a>.
+ </p>
</section>
</section>
@@ -219,21 +228,13 @@
If we have to define database tables that have to contain these classes
we have to choose one of the following solutions:
</p>
- <p>
- 1. Map all classes onto one table. A DDL for the table would look like:
- </p>
- <source><![CDATA[
-CREATE TABLE A_EXTENT
-(
- ID INT NOT NULL PRIMARY KEY,
- SOME_VALUE_FROM_A INT,
- SOME_VALUE_FROM_B INT
-)]]></source>
- <p>
- 2. Map each class to a distinct table and have all
- attributes from the base class in the derived class. DDL for the
- table could look like:
- </p>
+ <ol>
+ <li>
+ <p>
+ <a href="#table-per-class">Map each class of a hierarchy to a distinct table</a> and have all
+ attributes from the base class in the derived class. DDL for the
+ table could look like:
+ </p>
<source><![CDATA[
CREATE TABLE A
(
@@ -246,12 +247,27 @@
SOME_VALUE_FROM_A INT,
SOME_VALUE_FROM_B INT
)]]></source>
- <p>
- 3. Map each class to a distinct table, but do not map
- base class fields to derived classes. Use joins to materialize over
- all tables to materialize objects. DDL for the table would look
- like:
- </p>
+ </li>
+ <li>
+ <p>
+ <a href="#table-per-hierarchy">Map class hierarchy onto one table</a>. A DDL for the table would look like:
+ </p>
+ <source><![CDATA[
+CREATE TABLE A_EXTENT
+(
+ ID INT NOT NULL PRIMARY KEY,
+ SOME_VALUE_FROM_A INT,
+ SOME_VALUE_FROM_B INT
+ CLASS_NAME VARCHAR(150)
+)]]></source>
+ </li>
+ <li>
+ <p>
+ <a href="#table-per-subclass">Map subclass fields of a hierarchy to a distinct table</a>,
+ but do not map super class fields to derived classes. Use joins to materialize over
+ all tables to materialize objects. DDL for the table would look
+ like:
+ </p>
<source><![CDATA[
CREATE TABLE A
(
@@ -260,9 +276,11 @@
)
CREATE TABLE B
(
- A_ID INT NOT NULL,
+ ID INT NOT NULL PRIMARY KEY,
SOME_VALUE_FROM_B INT
)]]></source>
+ </li>
+ </ol>
<p>
OJB provides direct support for all three approaches.
</p>
@@ -273,9 +291,20 @@
approaches can be implemented by using OJB.
</p>
- <anchor id="classes-on-same-table"/>
+ <anchor id="table-per-class"/>
<section>
- <title>Mapping All Classes on the Same Table</title>
+ <title>Mapping Each Class of a Hierarchy to a Distinct Table (table per class)</title>
+ <p>
+ This is the most simple solution. Just write a complete
+ <a href="site:repository/class-descriptor">ClassDescriptor</a> for each class that contains
+ <a href="site:repository/field-descriptor">FieldDescriptors</a> for all
+ of the attributes, including inherited attributes.
+ </p>
+ </section>
+
+ <anchor id="table-per-hierarchy"/>
+ <section>
+ <title>Mapping Class Hierarchy on the Same Table (table per hierarchy)</title>
<p>
Mapping several classes on one table works well under OJB. There is
only one special situation that needs some attention:
@@ -434,17 +463,9 @@
</p>
</section>
+ <anchor id="table-per-subclass"/>
<section>
- <title>Mapping Each Class to a Distinct Table</title>
- <p>
- This is the most simple solution. Just write a complete
- ClassDescriptor for each class that contains FieldDescriptors for all
- of the attributes, including inherited attributes.
- </p>
- </section>
-
- <section>
- <title>Mapping Classes on Multiple Joined Tables</title>
+ <title>Mapping Each Subclass to a Distinct Table (table per subclass)</title>
<p>
### TODO: document changes made in 1.0.4 ###
</p>
No revision
No revision
1.3.2.21 +4 -2 db-ojb/src/doc/forrest/src/documentation/content/xdocs/site.xml
Index: site.xml
===================================================================
RCS file: /home/cvs/db-ojb/src/doc/forrest/src/documentation/content/xdocs/site.xml,v
retrieving revision 1.3.2.20
retrieving revision 1.3.2.21
diff -u -r1.3.2.20 -r1.3.2.21
--- site.xml 12 Dec 2005 02:51:12 -0000 1.3.2.20
+++ site.xml 16 Dec 2005 20:55:48 -0000 1.3.2.21
@@ -168,7 +168,9 @@
<which-collection-type href="#which-collection-type"/>
<extents href="#extents"/>
<callback href="#callback"/>
- <classes-on-same-table href="#classes-on-same-table"/>
+ <table-per-hierarchy href="#table-per-hierarchy"/>
+ <table-per-class href="#table-per-class"/>
+ <table-per-subclass href="#table-per-subclass"/>
</advanced-technique>
<query label="OJB queries" href="query.html">
<query-by-criteria href="#query-by-criteria"/>
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org