db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject cvs commit: db-ojb/xdocs tutorial3.xml
Date Sun, 28 Mar 2004 02:31:57 GMT
arminw      2004/03/27 18:31:57

  Modified:    xdocs    tutorial3.xml
  Log:
  update documentation to the new auto-xxx stuff
  
  Revision  Changes    Path
  1.32      +585 -252  db-ojb/xdocs/tutorial3.xml
  
  Index: tutorial3.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/xdocs/tutorial3.xml,v
  retrieving revision 1.31
  retrieving revision 1.32
  diff -u -r1.31 -r1.32
  --- tutorial3.xml	13 Dec 2003 21:48:27 -0000	1.31
  +++ tutorial3.xml	28 Mar 2004 02:31:56 -0000	1.32
  @@ -33,21 +33,36 @@
   <subsection name="table of contents">
   
   <ul>
  -  <li><A HREF="#Mapping 1:1 associations">Mapping 1:1 associations</A></li>
  +  <li>
  +      <A HREF="#Mapping 1:1 associations">Mapping 1:1 associations</A>
  +      <ul>
  +          <li><a href="#1:1 auto-xxx setting">1:1 auto-xxx setting</a></li>
  +      </ul>
  +  </li>
  +
     <li>
       <A HREF="#Mapping 1:n associations">Mapping 1:n associations</A>
       <ul>
  -      <li><A HREF="#Types Allowed for Implementing 1:n Associations">Types
Allowed for Implementing 1:n Associations</A></li>
  +        <li><A HREF="#Types Allowed for Implementing 1:n Associations">Types
Allowed for Implementing 1:n Associations</A></li>
  +        <li><a href="#1:n auto-xxx setting">1:n auto-xxx setting</a></li>
       </ul>
     </li>
  +
     <li>
       <A HREF="#Mapping m:n associations">Mapping m:n associations</A>
       <ul>
  -      <li><A HREF="#Manual decomposition into two 1:n associations">Manual
decomposition into two 1:n associations</A></li>
  -      <li><A HREF="#Support for Non-Decomposed m:n Mappings">Support for Non-Decomposed
m:n Mappings</A></li>
  +        <li><A HREF="#Manual decomposition into two 1:n associations">Manual
decomposition into two 1:n associations</A></li>
  +        <li><A HREF="#Support for Non-Decomposed m:n Mappings">Support for
Non-Decomposed m:n Mappings</A></li>
  +        <li><a href="#m:n auto-xxx setting">m:n auto-xxx setting</a></li>
  +    </ul>
  +  </li>
  +  <li>
  +      <A HREF="#Setting Load, Update, and Delete Cascading">Setting Load, Update,
and Delete Cascading</A>
  +      <ul>
  +        <li><a href="#auto-retrieve setting">auto-retrieve setting</a></li>
  +        <li><a href="#Link references">Link references</a></li>
       </ul>
     </li>
  -  <li><A HREF="#Setting Load, Update, and Delete Cascading">Setting Load, Update,
and Delete Cascading</A></li>
     <li>
       <A HREF="#Using Proxy Classes">Using Proxy Classes</A>
       <ul>
  @@ -93,6 +108,10 @@
   </subsection>
   </section>
   
  +
  +
  +
  +
   <section name="Mapping 1:1 associations">
     <p>
       As a sample for a simple association we take the reference from an
  @@ -218,7 +237,7 @@
       navigation may be added by including a reference from a ProductGroup to a
       single Article (for example, a sample article for the productgroup). To accomplish
       this we need to perform the following steps:
  -  </p>
  +
     <OL>
       <LI>
       Add a private Article attribute named <code>sampleArticle</code>
  @@ -256,9 +275,83 @@
       <foreignkey field-ref="sampleArticleId""/>
   </reference-descriptor>
     ]]></source>
  +</p>
   
  +<subsection name="1:1 auto-xxx setting">
  +<p>
  +    General info about the <code>auto-xxx</code> and <code>proxy</code>
attributes can be
  +    found <a href="#Setting Load, Update, and Delete Cascading">here</a>
  +</p>
  +
  +<p>
  +    <b>auto-retrieve</b><br/>
  +    See <a href="#auto-retrieve setting">here</a>
  +</p>
  +
  +<p>
  +<b>auto-update</b><br/>
  +<ul>
  +    <li>
  +        <b>none</b> On updating or inserting of the main object with <code>PersistenceBroker.store(...)</code>,
  +        the referenced object was NOT updated by default.The reference will be not <i>inserted</i>
or
  +        <i>updated</i>, the link to the reference (foreign key value to the
reference) on the main object
  +        will be not assigned automatic. The user has to link the main object and to store
the reference before
  +        the main object.
  +    </li>
  +    <li>
  +        <b>link</b> On updating or inserting of the main object with <code>PersistenceBroker.store(...)</code>,
  +        the FK assignment on the main object was done automatic. OJB read the PK from the
reference object and set these
  +        values as FK in main object. But the referenced object was not touched. If no reference
object was found, the FK
  +        will be nullified. (On insert it is allowed to set the FK without populate the
referenced object)
  +    </li>
  +    <li>
  +        <b>object</b> On updating or inserting of the main object with <code>PersistenceBroker.store(...)</code>,
  +        the reference object was stored first, then OJB does the same as in <i>link</i>.
  +    </li>
  +    <li>
  +        <b>false</b>
  +        Is equivalent to <i>link</i>.
  +    </li>
  +    <li>
  +        <b>true</b>
  +        Is equivalent to <i>object</i>.
  +    </li>
  +</ul>
  +</p>
  +
  +<p>
  +<b>auto-delete</b><br/>
  +<ul>
  +    <li>
  +        <b>none</b>
  +        On deleting an object with <code>PersistenceBroker.delete(...)</code>
the referenced object was
  +        NOT touched.
  +    </li>
  +    <li>
  +        <b>link</b>
  +        Is equivalent to <i>none</i>.
  +    </li>
  +    <li>
  +        <b>object</b>
  +        On deleting an object with <code>PersistenceBroker.delete(...)</code>
the referenced object was
  +        deleted too.
  +    </li>
  +    <li>
  +        <b>false</b>
  +        Is equivalent to <i>none</i>.
  +    </li>
  +    <li>
  +        <b>true</b>
  +        Is equivalent to <i>object</i>.
  +    </li>
  +</ul>
  +</p>
  +</subsection>
   </section>
   
  +
  +
  +
   <section name="Mapping 1:n associations">
     <p>
     We will take a different perspective from the previous exmaple for
  @@ -378,21 +471,25 @@
     it in the repository file. There is also no additional programming
     required. The following types are supported:</p>
     <OL>
  -          <LI><code>java.util.Collection,
  -          java.util.List, java.util.Vector</code> as in the example above.
  -          Internally OJB uses <code>java.util.Vector</code>
  -          to implement collections.</LI>
  -          <LI>Arrays (see the file <code>ProductGroupWithArray</code>).</LI>
  -          <LI>User-defined collections (see the file
  +        <LI><code>java.util.Collection,
  +        java.util.List, java.util.Vector</code> as in the example above.
  +        Internally OJB uses <code>java.util.Vector</code>
  +        to implement collections.</LI>
  +
  +        <LI>Arrays (see the file <code>ProductGroupWithArray</code>).</LI>
  +
  +        <LI>
  +          User-defined collections (see the file
             <code>ProductGroupWithTypedCollection</code>).
             A typical application for this approach are typed Collections. <br/>Here
             is some sample code from the Collection class <code>ArticleCollection</code>.
  -          This Collection is typed, i.e. It accepts only InterfaceArticle
  +          This Collection is typed, i.e. it accepts only InterfaceArticle
             objects for adding and will return InterfaceArticle objects with
             <code>get(int index)</code>. To let OJB
  -          handle such a user-defined Collection it must implement the callback
  -          interface <code>ManageableCollection</code>.
  -          This interface provides hooks that are called by OJB during object
  +          handle such a user-defined Collection it <b>must</b> implement the
callback
  +          interface <code>ManageableCollection</code> and the typed collection
class must be
  +          declared in the <i>collection-descriptor</i> using the <i>collection-class</i>
attribute.
  +          <code>ManageableCollection</code> provides hooks that are called
by OJB during object
             materialization, updating and deletion.</LI>
     </OL>
     <source><![CDATA[
  @@ -450,9 +547,97 @@
       }
   }
     ]]></source>
  +    <p>
  +        And the collection-descriptor have to declare this class:
  +        <source><![CDATA[
  +<collection-descriptor
  +    name="allArticlesInGroup"
  +    element-class-ref="org.apache.ojb.broker.Article"
  +    collection-class="org.apache.ojb.broker.ArticleCollection"
  +    auto-retrieve="true"
  +    auto-update="false"
  +    auto-delete="true"
  +>
  +    <inverse-foreignkey field-ref="productGroupId"/>
  +</collection-descriptor>
  +        ]]></source>
  +    </p>
   </subsection>
  +
  +<subsection name="1:n auto-xxx setting">
  +<p>
  +    General info about the <code>auto-xxx</code> and <code>proxy</code>
attributes can be
  +    found <a href="#Setting Load, Update, and Delete Cascading">here</a>
  +</p>
  +
  +<p>
  +    <b>auto-retrieve</b><br/>
  +    See <a href="#auto-retrieve setting">here</a>
  +</p>
  +
  +<p>
  +<b>auto-update</b><br/>
  +<ul>
  +    <li>
  +        <b>none</b> On updating or inserting of the main object with <code>PersistenceBroker.store(...)</code>,
  +        the referenced objects are NOT updated by default. The referenced objects will
be not <i>inserted</i> or
  +        <i>updated</i>, the referenced objects will not be linked (foreign
key assignment on referenced objects)
  +        automatic. The user has to link and to store the referenced objects after storing
the main object.
  +    </li>
  +    <li>
  +        <b>link</b> On updating or inserting of the main object with <code>PersistenceBroker.store(...)</code>,
  +        the referenced objects are NOT updated by default. The referenced objects will
be not <i>inserted</i> or
  +        <i>updated</i>, but the referenced objects will be linked automatic
(FK assignment).
  +    </li>
  +    <li>
  +        <b>object</b> On updating or inserting of the main object with <code>PersistenceBroker.store(...)</code>,
  +        the referenced objects will be linked and stored automatic.
  +    </li>
  +    <li>
  +        <b>false</b>
  +        Is equivalent to <i>link</i>.
  +    </li>
  +    <li>
  +        <b>true</b>
  +        Is equivalent to <i>object</i>.
  +    </li>
  +</ul>
  +</p>
  +<p>
  +<b>auto-delete</b><br/>
  +<ul>
  +    <li>
  +        <b>none</b>
  +        On deleting an object with <code>PersistenceBroker.delete(...)</code>
the referenced objects are
  +        NOT touched.
  +    </li>
  +    <li>
  +        <b>link</b>
  +        Is equivalent to <i>none</i>.
  +    </li>
  +    <li>
  +        <b>object</b>
  +        On deleting an object with <code>PersistenceBroker.delete(...)</code>
the referenced objects will be
  +        deleted too.
  +    </li>
  +    <li>
  +        <b>false</b>
  +        Is equivalent to <i>none</i>.
  +    </li>
  +    <li>
  +        <b>true</b>
  +        Is equivalent to <i>object</i>.
  +    </li>
  +</ul>
  +</p>
  +</subsection>
  +
   </section>
   
  +
  +
  +
  +
   <section name="Mapping m:n associations">
   
   <p>
  @@ -660,74 +845,76 @@
   </p>
   
   <source><![CDATA[
  -   <class-descriptor
  -      class="org.apache.ojb.broker.Person"
  -      table="PERSON"
  -   >
  -      <field-descriptor
  -         name="id"
  -         column="ID"
  -         jdbc-type="INTEGER"
  -         primarykey="true"
  -         autoincrement="true"
  -      />
  -      <field-descriptor
  -         name="firstname"
  -         column="FIRSTNAME"
  -         jdbc-type="VARCHAR"
  -      />
  -      <field-descriptor
  -         name="lastname"
  -         column="LASTNAME"
  -         jdbc-type="VARCHAR"
  -      />
  -      ...
  -      <collection-descriptor
  -         name="projects"
  -         element-class-ref="org.apache.ojb.broker.Project"
  -         auto-retrieve="true"
  -         auto-update="true"
  -         indirection-table="PERSON_PROJECT"
  -      >
  -         <fk-pointing-to-this-class column="PERSON_ID"/>
  -         <fk-pointing-to-element-class column="PROJECT_ID"/>
  -      </collection-descriptor>
  -   </class-descriptor>
  +<class-descriptor
  +  class="org.apache.ojb.broker.Person"
  +  table="PERSON"
  +>
  +  <field-descriptor
  +     name="id"
  +     column="ID"
  +     jdbc-type="INTEGER"
  +     primarykey="true"
  +     autoincrement="true"
  +  />
  +  <field-descriptor
  +     name="firstname"
  +     column="FIRSTNAME"
  +     jdbc-type="VARCHAR"
  +  />
  +  <field-descriptor
  +     name="lastname"
  +     column="LASTNAME"
  +     jdbc-type="VARCHAR"
  +  />
  +  ...
  +  <collection-descriptor
  +     name="projects"
  +     collection-class="org.apache.ojb.broker.util.collections.ManageableArrayList"
  +     element-class-ref="org.apache.ojb.broker.Project"
  +     auto-retrieve="true"
  +     auto-update="true"
  +     indirection-table="PERSON_PROJECT"
  +  >
  +     <fk-pointing-to-this-class column="PERSON_ID"/>
  +     <fk-pointing-to-element-class column="PROJECT_ID"/>
  +  </collection-descriptor>
  +</class-descriptor>
   
   <!-- Definitions for org.apache.ojb.broker.Project -->
  -   <class-descriptor
  -      class="org.apache.ojb.broker.Project"
  -      table="PROJECT"
  -   >
  -      <field-descriptor
  -         name="id"
  -         column="ID"
  -         jdbc-type="INTEGER"
  -         primarykey="true"
  -         autoincrement="true"
  -      />
  -      <field-descriptor
  -         name="title"
  -         column="TITLE"
  -         jdbc-type="VARCHAR"
  -      />
  -      <field-descriptor
  -         name="description"
  -         column="DESCRIPTION"
  -         jdbc-type="VARCHAR"
  -      />
  -      ...
  -      <collection-descriptor
  -         name="persons"
  -         element-class-ref="org.apache.ojb.broker.Person"
  -         auto-retrieve="true"
  -         auto-update="false"
  -         indirection-table="PERSON_PROJECT"
  -      >
  -         <fk-pointing-to-this-class column="PROJECT_ID"/>
  -         <fk-pointing-to-element-class column="PERSON_ID"/>
  -      </collection-descriptor>
  -   </class-descriptor>
  +<class-descriptor
  +  class="org.apache.ojb.broker.Project"
  +  table="PROJECT"
  +>
  +  <field-descriptor
  +     name="id"
  +     column="ID"
  +     jdbc-type="INTEGER"
  +     primarykey="true"
  +     autoincrement="true"
  +  />
  +  <field-descriptor
  +     name="title"
  +     column="TITLE"
  +     jdbc-type="VARCHAR"
  +  />
  +  <field-descriptor
  +     name="description"
  +     column="DESCRIPTION"
  +     jdbc-type="VARCHAR"
  +  />
  +  ...
  +  <collection-descriptor
  +     name="persons"
  +     collection-class="org.apache.ojb.broker.util.collections.ManageableArrayList"
  +     element-class-ref="org.apache.ojb.broker.Person"
  +     auto-retrieve="true"
  +     auto-update="false"
  +     indirection-table="PERSON_PROJECT"
  +  >
  +     <fk-pointing-to-this-class column="PROJECT_ID"/>
  +     <fk-pointing-to-element-class column="PERSON_ID"/>
  +  </collection-descriptor>
  +</class-descriptor>
   ]]></source>
   <p>
   That is all that needs to be configured! See the code in class
  @@ -736,102 +923,159 @@
   <code>Project</code> and <code>Role</code>.
   </p>
   </subsection>
  -</section>
   
  -<section name="Setting Load, Update, and Delete Cascading">
  +<subsection name="m:n auto-xxx setting">
   <p>
  -As shown in the sections on 1:1 and 1:n mappings, OJB manages
  -associations (or object references in Java terminology) by declaring
  -special Reference and Collection Descriptors. These Descriptor may
  -contain some additional information that modifies OJB's behaviour on
  -object materialization, updating and deletion. If nothing is
  -specified default values are assumed:</p>
  -<OL>
  -    <LI>
  -	  <b><code>auto-retrieve="true"</code></b><br/>
  -      By default materializing an Object from the RDBMS with
  -      <code>PersistenceBroker.getObjectByQuery(...)</code> cause all
  -      its referenced objects (both 1:1 and 1:n associations) to be
  -      materialized as well.
  -      (If OJB is configured to use proxies, the referenced objects are
  -      not materialized immmediately, but lazy loading proxy objects are used
  -      instead.)
  -    </LI>
  -    <LI>
  -	  <b><code>auto-update="false"</code></b><br/>
  -      On updating or inserting an object with
  -      <code>PersistenceBroker.store(...)
  -      </code>referenced objects are NOT updated by default.  
  -    </LI>
  -    <LI>
  -	  <b><code>auto-delete="false"</code></b><br/>
  -      On deleting an object with <code>PersistenceBroker.delete(...)
  -      </code>referenced objects are NOT deleted by default.
  -    </LI>
  -</OL>
  +    General info about the <code>auto-xxx</code> and <code>proxy</code>
attributes can be
  +    found <a href="#Setting Load, Update, and Delete Cascading">here</a>
  +</p>
  +
  +<p>
  +    <b>auto-retrieve</b><br/>
  +    See <a href="#auto-retrieve setting">here</a>
  +</p>
  +
  +<p>
  +<b>auto-update</b><br/>
  +<ul>
  +    <li>
  +        <b>none</b> On updating or inserting of the main object with <code>PersistenceBroker.store(...)</code>,
  +        the referenced objects are NOT updated by default. The referenced objects will
be not <i>inserted</i> or
  +        <i>updated</i>, the referenced objects will not be linked (creation
of FK entries in the indirection table)
  +        automatic. The user has to store the main object, the referenced objects and to
link the
  +        m:n relation after storing of all objects.
  +    </li>
  +    <li>
  +        <b>link</b> On updating or inserting of the main object with <code>PersistenceBroker.store(...)</code>,
  +        the referenced objects are NOT updated by default. The referenced objects will
be not <i>inserted</i> or
  +        <i>updated</i>, but the m:n relation was linked automatic (creation
of FK entries in the indirection table).
  +        <br/>NOTE: Make sure that the referenced objects exist in database before
store main object.
  +    </li>
  +    <li>
  +        <b>object</b> On updating or inserting of the main object with <code>PersistenceBroker.store(...)</code>,
  +        the referenced objects will be linked and stored automatic.
  +    </li>
  +    <li>
  +        <b>false</b>
  +        Is equivalent to <i>link</i>.
  +    </li>
  +    <li>
  +        <b>true</b>
  +        Is equivalent to <i>object</i>.
  +    </li>
  +</ul>
  +</p>
   <p>
  -	If no special settings are
  -	made in the reference-descriptor or collection-descriptor elements,
  -	these default settings are used.
  +<b>auto-delete</b><br/>
  +<ul>
  +    <li>
  +        <b>none</b>
  +        On deleting an object with <code>PersistenceBroker.delete(...)</code>
the referenced objects are
  +        NOT touched.
  +    </li>
  +    <li>
  +        <b>link</b>
  +        On deleting an object with <code>PersistenceBroker.delete(...)</code>
the m:n relation will be
  +        <i>unlinked</i> (all entries of the main object in the indirection
table will be removed).
  +    </li>
  +    <li>
  +        <b>object</b>
  +        On deleting an object with <code>PersistenceBroker.delete(...)</code>
all referenced objects will be
  +        deleted too.
  +    </li>
  +    <li>
  +        <b>false</b>
  +        Is equivalent to <i>link</i>.
  +    </li>
  +    <li>
  +        <b>true</b>
  +        Is equivalent to <i>object</i>.
  +    </li>
  +</ul>
   </p>
  +</subsection>
  +
  +</section>
  +
  +
  +
  +
  +<section name="Setting Load, Update, and Delete Cascading">
  +
   <p>
  +    As shown in the sections on 1:1, 1:n and m:n mappings, OJB manages
  +    associations (or object references in Java terminology) by declaring
  +    special Reference and Collection Descriptors. These Descriptor may
  +    contain some additional information that modifies OJB's behaviour on
  +    object materialization, updating and deletion.
  +    <br/>
  +    The behaviour depends on specific attributes
  +    <ul>
  +        <li><i>auto-retrieve</i> - possible settings are <i>false</i>,
<i>true</i>. If not specified in the
  +        descriptor the default value is <i>true</i></li>
  +        <li><i>auto-update</i> - possible settings are <i>none</i>,
<i>link</i>, <i>object</i> and deprecated
  +            [<i>false</i>, <i>true</i>]. If not specified in the
descriptor the default value is <i>false</i></li>
  +        <li><i>auto-delete</i> - possible settings are <i>none</i>,
<i>link</i>, <i>object</i> and deprecated
  +            [<i>false</i>, <i>true</i>]. If not specified in the
descriptor the default value is <i>false</i></li>
  +    </ul>
  +    <p>
   	<b>These default settings are mandatory for proper operation of the ODMG
   	and JDO implementation.</b>
  +    </p>
  +    The attribute <i>auto-update</i> and <i>auto-delete</i> are
described in detail in the corresponding sections
  +    for <a href="#Mapping 1:1 associations">1:1</a>
  +    , <a href="#Mapping 1:n associations">1:n</a>
  +    and <a href="#Mapping m:n associations">m:n</a> references.
  +    The <i>auto-retrieve</i> setting is described below:
   </p>
   
  +
  +<subsection name="auto-retrieve setting">
   <p>
  -	The default settings can be changed as follows:
  -	<OL>
  -		<LI>
  -			<b><code>auto-retrieve="false"</code></b><br/>
  -			With this setting references and and Collection attributes 
  -			will not be loaded by OJB on loading instances.
  -			OJB will also not replace those attributes with dynamic proxies.
  -			These attributes simply stay set to <code>null</code>.
  -			If such attributes must be accessed later, the user is responsible 
  -			to load them manually with the 
  -			<code>PersistenceBroker.retrieveReference(...)</code> 
  -			<code>PersistenceBroker.retrieveAllReferences(...)</code>  methods.
  -		</LI>
  -		<LI>
  -			<b><code>auto-update="true"</code></b><br/>
  -			If this flag is set on a reference- or collection-attribute
  -			the referenced objects are also persisted (inserted or updated) to the database.
  -			Objects that have been removed from collections are not automatically
  -			handled by the PersistenceBroker.
  -			By using special collections like the RemovalAwareCollection you can 
  -			achieve automatic handling of deletion from collections. 
  -		</LI>
  -		<LI>
  -			<b><code>auto-delete="true"</code></b><br/>
  -			If this flag is set on a reference- or collection-attribute
  -			the referenced objects are also deleted if an instance of
  -			the persistent class is deleted.
  -			The PersistenceBroker does <b>not</b> provide a full cascading delete,
  -			but does only remove objects that are actually referenced.
  -			Assume you load a master object that has a collection of 5 detail items
  -			and remove 2 of them. If the master object is deleted only the three
  -			remaining detail items are deleted. As the other two detail items
  -			are not deleted, this could result in foreign key violations
  -			if handled carelessly.
  -		</LI>		
  -	</OL>
  +    The <code>auto-retrieve</code> attribute used in <code>reference-descriptor</code>
or <code>collection-descriptor</code>
  +    elements handles the loading behaviour of references (1:1, 1:n and m:n):
  +    <ul>
  +    <li>
  +        <b>false</b> If set <i>false</i> the referenced objects
will not be materialized on object materialization.
  +        The user has to materialize the n-side objects (or single object for 1:1) by hand
using one of the following
  +        service methods of the <code>PersistenceBroker</code> class:
  +        <source>
  +PersistenceBroker.retrieveReference(Object obj, String attributeName)
  +or
  +PersistenceBroker.retrieveAllReferences(Object obj)
  +        </source>
  +        The first method load only the specified reference, the second one loads all references
declared
  +        for the given object.
  +        <br/><b>NOTE:</b> Be careful when using "opposite" settings,
e.g. if you declare a 1:1 reference with
  +        auto-retrieve="false" and auto-update="object" (or "true" or "link"). Before you
can perform an update
  +        on the main object, you have to "retrieve" the 1:1 reference. Otherwise you will
end up with an nullified
  +        reference, because OJB assume the reference was removed.
  +    </li>
  +    <li>
  +        <b>true</b> If set <i>true</i> the referenced object (in
this case all n-side objects) will be automatic loaded
  +        by OJB when the main object was materialized.
  +    </li>
  +</ul>
  +
  +    <p>
  +        If OJB is configured to use proxies, the referenced objects are
  +        not materialized immmediately, but lazy loading proxy objects are used
  +        instead.
  +    </p>
   </p>
   
   <p>
   	In the following code sample, a reference-descriptor and a collection-descriptor
   	are configured to use cascading retrieval (<code>auto-retrieve="true"</code>),
  -	insert, and update (<code>auto-update="true"</code>) and delete
  -	(<code>auto-delete="true"</code>) operations:
  -</p>
  -
  +	cascading insert/update (<code>auto-update="object"</code> or <code>auto-update="true"</code>)
  +    and cascading delete (<code>auto-delete="object"</code> or <code>auto-delete="true"</code>)
operations:
   <source><![CDATA[
         <reference-descriptor
            name="productGroup"
            class-ref="org.apache.ojb.broker.ProductGroup"
            auto-retrieve="true"
  -         auto-update="true"
  -         auto-delete="true"
  +         auto-update="object"
  +         auto-delete="object"
         >
            <foreignkey field-ref="productGroupId"/>
         </reference-descriptor>
  @@ -840,17 +1084,112 @@
            name="allArticlesInGroup"
            element-class-ref="org.apache.ojb.broker.Article"
            auto-retrieve="true"
  -         auto-update="true"
  -         auto-delete="true"
  +         auto-update="object"
  +         auto-delete="object"
            orderby="articleId"
            sort="DESC"
         >
            <inverse-foreignkey field-ref="productGroupId"/>
         </collection-descriptor>
   ]]></source>
  +</p>
  +</subsection>
  +
  +
  +<subsection name="Link references">
  +<p>
  +    <p>If in <code>reference-descriptor</code> or <code>collection-descriptor</code>
the <i>auto-update</i> or
  +    <i>auto-delete</i> attributes are set to <i>none</i>, OJB do
not touch the referenced objects on insert,
  +    update or delete operations of the main object. The user has to take care of correct
handling of
  +    referenced objects.
  +    </p>
  +    <p>
  +    One important thing is assignment of the FK values. The assign of the FK values is
transcribed with
  +    <b><i>link references</i></b> in OJB. In 1:1 references the
main object has a FK to the referenced object, in 1:n
  +    references the referenced objects has a FK to the main object and in non-decomposed
m:n relations
  +    a indirection table with FK values from both sides was used.
  +    </p>
  +    <p>
  +    OJB provide some helper methods for manual reference linking (assignment of the FK)
in
  +    <code>org.apache.ojb.broker.util.BrokerHelper</code> class.
  +<source>
  +    public void link(Object obj, boolean insert)
  +    public void unlink(Object obj)
  +    public boolean link(Object obj, String attributeName, boolean insert)
  +    public boolean unlink(Object obj, String attributeName)
  +</source>
  +    These methods are accessible via <code>org.apache.ojb.broker.PersistenceBroker</code>:
  +<source>
  +    BrokerHelper bh = broker.serviceBrokerHelper();
  +</source>
  +    <p>
  +        <b>NOTE:</b> The <i>link/unlink</i> methods are only useful
if you set auto-update/-delete to <i>none</i>. In
  +        all other cases OJB handle the link/unlink of references internally. It is also
possible to set all FK values by
  +        hand without using the link/unlink service methods.
  +    </p>
  +    <p>
  +    <b>Examples</b><br/>
  +    <p>
  +    Now we prepared for some example. Say class <code>Movie</code> has an m:n
reference with class
  +    <code>Actor</code> and we want to store an Movie object with a list of
Actor objects. The auto-update
  +    setting of collection-descriptor for Movie is <i>none</i>:
  +<source>
  +    broker.beginTransaction();
  +    // store main object first
  +    broker.store(movie);
  +    //now we store the right-side objects
  +    Iterator it = movie.getActors().iterator();
  +    while(it.hasNext())
  +    {
  +        Object actor = it.next();
  +        broker.store(actor);
  +    }
  +    // now both side exist and we can link the references
  +    broker.serviceBrokerHelper().link(movie, "actors", true);
  +    /*
  +    alternative call
  +    broker.serviceBrokerHelper().link(movie, true);
  +    */
  +    broker.commitTransaction();
  +</source>
  +    </p>
  +    First store the main object and the references, then use
  +    <code>broker.serviceBrokerHelper().link(movie, "actors", true)</code> to
link the main object with the
  +    references. In case of a m:n relation linking create all FK entries in the indirection
table.
  +    </p>
  +    <p>
  +    In the next examples we want to manually delete a <code>Project</code>
object with a 1:n relation to class
  +        <code>SubProject</code>. In the example, the Project object has load
all SubProject objects and we want to
  +        delete the Project but <b>don't</b> want to delete the referenced SubProjects
too (don't ask if this make
  +        sense ;-)). SubProject has an FK to Project, so we first have to <i>unlink</i>
the reference from the
  +        main object to the references to avoid integrity constraint violation. Then we
can delete the main object:
  +<source>
  +    broker.beginTransaction();
  +    // first unlink the n-side references
  +    broker.serviceBrokerHelper().unlink(project, "subProjects");
  +
  +    // update the n-side references, store SubProjects with nullified FK
  +    Iterator it = project.getSubProjects().iterator();
  +    while(it.hasNext())
  +    {
  +        SubProject subProject = (SubProject) it.next();
  +        broker.store(subProject);
  +    }
  +
  +    // now delete the main object
  +    broker.delete(project);
  +    broker.commitTransaction();
  +</source>
  +        </p>
  +    </p>
  +</p>
  +</subsection>
   
   </section>
   
  +
  +
  +
   <section name="Using Proxy Classes">
   <p>
   Proxy classes can be used for &quot;lazy loading&quot; aka &quot;lazy
  @@ -1412,7 +1751,7 @@
   <p>
       OJB provides direct support for all three approaches. <br/>
       <b>But it's currently not recommended to mix mapping strategies
  -    within the same hierarchy !</b> 
  +    within the same hierarchy !</b>
       <br/>
       In the following we demonstrate how these mapping
       approaches can be implemented by using OJB.
  @@ -1436,9 +1775,9 @@
       loading objects from the table OJB checks this attribute and
       instantiates objects of this type.
       <br/>
  -    <b>The criterion for <code>ojbConcreteClass</code> is statically
added to the 
  -    query in class <code>QueryFactory</code> and it therefore appears in 
  -    the select-statement for each extent. This means that mixing mapping strategies should
be avoided.</b> 
  +    <b>The criterion for <code>ojbConcreteClass</code> is statically
added to the
  +    query in class <code>QueryFactory</code> and it therefore appears in
  +    the select-statement for each extent. This means that mixing mapping strategies should
be avoided.</b>
   </p>
   <p>
       There is sample code for this feature in the method
  @@ -1604,48 +1943,51 @@
   
   <source><![CDATA[
   <!-- Definitions for org.apache.ojb.broker.A -->
  -   <class-descriptor
  -      class="org.apache.ojb.broker.A"
  -      table="A_TABLE"
  -   >
  -      <field-descriptor
  -         name="id"
  -         column="ID"
  -         jdbc-type="INTEGER"
  -         primarykey="true"
  -         autoincrement="true"
  -      />
  -      <field-descriptor
  -         name="someValueFromA"
  -         column="VALUE_"
  -         jdbc-type="INTEGER"
  -      />
  -   </class-descriptor>
  -
  -   <class-descriptor
  -      class="org.apache.ojb.broker.B"
  -      table="B_TABLE"
  -   >
  -      <field-descriptor
  -         name="id"
  -         column="ID"
  -         jdbc-type="INTEGER"
  -         primarykey="true"
  -         autoincrement="true"
  -      />
  -
  -      <field-descriptor
  -         name="someValueFromB"
  -         column="VALUE_"
  -         jdbc-type="INTEGER"
  -      />
  -
  -      <reference-descriptor name="super"
  -        class-ref="org.apache.ojb.broker.A">
  -        <foreignkey field-ref="id" />
  -      </reference-descriptor>
  +<class-descriptor
  +    class="org.apache.ojb.broker.A"
  +    table="A_TABLE"
  +>
  +    <field-descriptor
  +        name="id"
  +        column="ID"
  +        jdbc-type="INTEGER"
  +        primarykey="true"
  +        autoincrement="true"
  +    />
  +    <field-descriptor
  +        name="someValueFromA"
  +        column="VALUE_"
  +        jdbc-type="INTEGER"
  +    />
  +</class-descriptor>
   
  -   </class-descriptor>
  +<class-descriptor
  +    class="org.apache.ojb.broker.B"
  +    table="B_TABLE"
  +>
  +    <field-descriptor
  +        name="id"
  +        column="ID"
  +        jdbc-type="INTEGER"
  +        primarykey="true"
  +        autoincrement="true"
  +    />
  +
  +    <field-descriptor
  +        name="someValueFromB"
  +        column="VALUE_"
  +        jdbc-type="INTEGER"
  +    />
  +
  +    <reference-descriptor name="super"
  +        class-ref="org.apache.ojb.broker.A"
  +        auto-retrieve="true"
  +        auto-update="true"
  +        auto-delete="true"
  +    >
  +        <foreignkey field-ref="id"/>
  +    </reference-descriptor>
  +</class-descriptor>
   ]]></source>
   <p>
   As you can see from this mapping we need a special reference-descriptor
  @@ -1659,13 +2001,14 @@
   keyword defining the JOIN to the baseclass.
   </p>
   <p>
  -Auto-update must be <b>true</b> (this is the default) to force insertion of
A when inserting B.
  -So you'd better not define any auto-settings for this reference-descriptor !
  +Auto-update must be <b>true</b> to force insertion of A when inserting B.
  +So have to define a <i>auto-update</i> true setting for this reference-descriptor!
  +In most cases it's also useful to enable <i>auto-delete</i>.
   </p>
   <p>
   <b>
  -Be aware that this sample does not declare <code>org.apache.ojb.broker.B</code>

  -to be an extent of <code>org.apache.ojb.broker.A</code>. Using extents here
will 
  +Be aware that this sample does not declare <code>org.apache.ojb.broker.B</code>
  +to be an extent of <code>org.apache.ojb.broker.A</code>. Using extents here
will
   lead to problems (instatiating the wrong class) because the primary key is not
   unique within the hiearchy defined in the repository.
   </b>
  @@ -2220,15 +2563,16 @@
   			provide empty implementations for all required mthods.
   		</li>
   		<li>
  -			implement the method <code>afterStore(PersistenceBroker broker)</code> to
perform
  +			implement the method <code>afterUpdate(PersistenceBroker broker)</code>
and
  +            <code>afterInsert(PersistenceBroker broker)</code> to perform
   			your intended logic.
   		</li>
   	</ol>
   </p>
   <p>
  -	In the following you see code from a class <code>DBAutoIncremented</code>
  -	that does not use the OJB sequence numbering, but relies on a database
  -	specific implementation of autoincremented primary key values.
  +	In the following "for demonstration only code" you see a class <code>DBAutoIncremented</code>
  +	that does not use the OJB sequence numbering (more <a href="sequencemanager.html">info
here</a>),
  +    but relies on a database specific implementation of autoincremented primary key values.
   	<br/>
   	When the broker is storing such an instance the DB assigns an autoincrement
   	value to the primary key column mapped to the attribute <code>m_id</code>.
  @@ -2250,50 +2594,48 @@
       {
       }
   
  +    public void afterUpdate(PersistenceBroker broker)
  +    {
  +    }
  +
       /**
        * after storing a new instance reflect the
        * autoincremented PK value
        * back into the PK attribute.
        */
  -    public void afterStore(PersistenceBroker broker)
  +    public void afterInsert(PersistenceBroker broker)
       {
           try
           {
               // remove object from cache to ensure we are retrieving a
               // copy that is in sync with the database.
  -            broker.removeFromCache(this;)
  +            broker.removeFromCache(this);
   
               Class clazz = getClass();
               ClassDescriptor cld = broker.getClassDescriptor(clazz);
  -            PersistentField idField =
  -                cld
  -                    .getFieldDescriptorByName(ID_ATTRIBUTE_NAME)
  -                    .getPersistentField();
  +            PersistentField idField = cld
  +                        .getFieldDescriptorByName(ID_ATTRIBUTE_NAME)
  +                        .getPersistentField();
  +            // retrieve the object again with a query
  +            // on all non-id attributes.
  +            Object object =
  +                broker.getObjectByQuery(
  +                    buildQueryOnAllNonIdAttributes(clazz, cld));
   
  -            if (hasNotBeenSet(idField))
  +            if (object == null)
               {
  -
  -                // retrieve the object again with a query
  -                // on all non-id attributes.
  -                Object object =
  -                    broker.getObjectByQuery(
  -                        buildQueryOnAllNonIdAttributes(clazz, cld));
  -
  -                if (object == null)
  -                {
  -                    throw new PersistenceBrokerException(
  -                        "cannot assign ID to "
  -                            + this
  -                            + " ("
  -                            + clazz
  -                            + ")"
  -                            + " because lookup by attributes failed");
  -                }
  -
  -                // set id attribute with the value
  -                // assigned by the database.
  -                idField.set(this, idField.get(object));
  +                throw new PersistenceBrokerException(
  +                    "cannot assign ID to "
  +                        + this
  +                        + " ("
  +                        + clazz
  +                        + ")"
  +                        + " because lookup by attributes failed");
               }
  +
  +            // set id attribute with the value
  +            // assigned by the database.
  +            idField.set(this, idField.get(object));
           }
       }
   
  @@ -2308,7 +2650,7 @@
       /**
        * returns a query that identifies an object by all its non-
        * primary key attributes.
  -     * this method is only safe, if these values are unique!
  +     * NOTE: This method is only safe, if these values are unique!
        */
       private Query buildQueryOnAllNonIdAttributes(
           Class clazz,
  @@ -2337,15 +2679,6 @@
               }
           }
           return QueryFactory.newQuery(clazz, crit);
  -    }
  -
  -    /**
  -     * returns true if attribute idField == 0,
  -     * else false.
  -     */
  -    private boolean hasNotBeenSet(PersistentField idField)
  -    {
  -        return (((Integer) idField.get(this)).intValue() == 0);
       }
   }
   ]]></source>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message