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/forrest/src/documentation/content/xdocs site.xml
Date Mon, 26 Apr 2004 18:25:21 GMT
arminw      2004/04/26 11:25:21

  Modified:    forrest/src/documentation/content/xdocs/docu
                        howto-use-anonymous-keys.xml faq.xml
                        pb-tutorial.xml advanced-technique.xml
                        mapping-tutorial.xml testsuite.xml testwrite.xml
               forrest/src/documentation/content/xdocs site.xml
  Added:       forrest/src/documentation/content/xdocs/docu
                        sequencemanager.xml
  Log:
  adapted docs + update
  
  Revision  Changes    Path
  1.2       +83 -17    db-ojb/forrest/src/documentation/content/xdocs/docu/howto-use-anonymous-keys.xml
  
  Index: howto-use-anonymous-keys.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/forrest/src/documentation/content/xdocs/docu/howto-use-anonymous-keys.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- howto-use-anonymous-keys.xml	22 Apr 2004 19:29:50 -0000	1.1
  +++ howto-use-anonymous-keys.xml	26 Apr 2004 18:25:20 -0000	1.2
  @@ -54,26 +54,68 @@
               </p>
               <source><![CDATA[
   {
  -Foo parent = new SomeFooType();
   Foo child = new SomeOtherFooType();
  -parent.addChild(child);
  +Foo parent = new SomeFooType();
  +child.setParent(parent);
   child.setParentId(parent.getId());
   }]]></source>
               <p>
                   This is double the work required - you set up the object relationship, then set up the key
  -                relationship.
  +                relationship. OJB knows about the relationship of the objects, thus it is only needed to
  +                do
               </p>
  +<source><![CDATA[
  +{
  +Foo child = new Foo();
  +Foo parent = new Foo();
  +child.setParent(parent);
  +}]]></source>
               <p>
  -                OJB can provide transparent key relationship maintenance behind the scenes via
  +                OJB can provide transparent key relationship maintenance behind the scenes for
  +                <link href="site:basic-technique/one-to-one">1:1 relations</link> via
                   <strong>anonymous access fields</strong>. As object relationships change, the relationships
  -                will be propogated into the key values without the Java object ever being aware of a
  -                relational key being in use.
  +                will be propogated into the key values without the <em>Java object ever being aware of a
  +                relational key</em> being in use. This means that the java object does not need to
  +                specify a FK field for the reference.
  +            </p>
  +            <p>
  +                Without use of <em>anonymous keys</em> class <code>Foo</code> have to look like:
  +            </p>
  +            <source><![CDATA[
  +class Foo
  +{
  +    Integer id;
  +    Integer fkParentFoo;
  +    Foo parent;
  +
  +    // optional getter/setter
  +    ....
  +{
  +            ]]></source>
  +            <p>
  +                When using <em>anonymous keys</em> the FK field will become obsolete:
               </p>
  +            <source><![CDATA[
  +class Foo
  +{
  +    Integer id;
  +    Foo parent;
  +
  +    // optional getter/setter
  +    ....
  +{
  +            ]]></source>
  +            <note>
  +                Under specific conditions it's also possible to use anonymous keys for other relations
  +                or primary keys. More info
  +                <link href="site:advanced-technique/anonymous-keys">in advanced-technique section</link>.
  +            </note>
           </section>
   
   
           <section>
               <title>How it works</title>
  +            <anchor id="how-it-works"/>
               <p>
                   To play for safety it is mandatory to understand how this feature is working. More information
                   how it works <link href="site:advanced-technique/anonymous-keys">please see here</link>.
  @@ -91,7 +133,9 @@
               <section>
                   <title>The Code</title>
                   <p>
  -                    Take the following classes designed to model a particular problem domain. They may do it reasonably well, or may not. Presume they model it perfectly well for the problem being solved.
  +                    Take the following classes designed to model a particular problem domain. They may do
  +                    it reasonably well, or may not. Presume they model it perfectly well for the problem
  +                    being solved.
                   </p>
                   <source><![CDATA[
   public class Desk
  @@ -203,7 +247,8 @@
               <section>
                   <title>The Database</title>
                   <p>
  -                    When we need to store our instances in a database we use a fairly typical table per class persistance model.
  +                    When we need to store our instances in a database we use a fairly typical table per class
  +                    persistance model.
                   </p>
                   <source><![CDATA[
   CREATE TABLE finish
  @@ -236,16 +281,26 @@
       FOREIGN KEY (drawer_id) REFERENCES drawer(id)
   );]]></source>
                   <p>
  -                    At the database level the possible relationships need to be explicitely defined by teh foreign key constraints. These model all the possible object relationships according to the domain model (until generics enter the Java language for the collections API, this is technically untrue for the classes used here).
  +                    At the database level the possible relationships need to be explicitely defined by the
  +                    foreign key constraints. These model all the possible object relationships according
  +                    to the domain model (until generics enter the Java language for the collections API,
  +                    this is technically untrue for the classes used here).
                   </p>
               </section>
               <section>
                   <title>The Repository Configuration</title>
                   <p>
  -                    When we go to map the classes to the database, it is almost a one-to-one property to field mapping. The exception here is the primary key on each entity. This is meaningless information in Java, so we would like to keep it out of the object model. Anonymous access keys allow us to do that.
  +                    When we go to map the classes to the database, it is almost a one-to-one property to
  +                    field mapping. The exception here is the primary key on each entity. This is meaningless
  +                    information in Java, so we would like to keep it out of the object model. Anonymous access
  +                    keys allow us to do that.
                   </p>
                   <p>
  -                    The repository.xml must know about the database columns used for referential integrity, but OJB can maintain the foreign key relationships behind the scenes - freeing the developer to focus on more accurate modeling of her objects to the problem, instead of the the persistance mechanism. Doing this is also very simple - in the repository.xml file mark the field descriptors with a
  +                    The repository.xml must know about the database columns used for referential integrity, but
  +                    OJB can maintain the foreign key relationships behind the scenes - freeing the developer
  +                    to focus on more accurate modeling of her objects to the problem, instead of the the
  +                    persistance mechanism. Doing this is also very simple - in the repository.xml file mark
  +                    the field descriptors with a
                       <code>access="anonymous"</code> attribute.
                   </p>
                   <source><![CDATA[
  @@ -360,18 +415,29 @@
           />
   </class-descriptor>]]></source>
                   <p>
  -                    Look first at the class descriptor for the Thing class. Notice the field-descriptor with the name attribute "drawerId". This field is labeled as anonymous access. Because it is anonymous access OJB will not attempt to assign the value here to a "drawerId" field or property on the Thing class. Normally the name attribute is used as the Java name for the attribute, in this case it is not. The name is still required because it is used as an indicated for references to this anonymous field.
  +                    Look first at the class descriptor for the Thing class. Notice the field-descriptor with
  +                    the name attribute "drawerId". This field is labeled as anonymous access. Because it is
  +                    anonymous access OJB will not attempt to assign the value here to a "drawerId" field or
  +                    property on the Thing class. Normally the name attribute is used as the Java name for the
  +                    attribute, in this case it is not. The name is still required because it is used as an
  +                    indicated for references to this anonymous field.
                   </p>
                   <p>
  -                    In the field descriptor for Drawer, look at the collection descriptor with the name "stuffInDrawer". This collection descriptor references a foreign key with the
  -                    <code>field-ref="drawerId"</code>. This reference is to the anonymous field descriptor in the Thing descriptor. The field-ref matches to the name in the descriptor whether or not the name also maps to the Java attribute name. This dual use of
  +                    In the field descriptor for Drawer, look at the collection descriptor with the name
  +                    <em>stuffInDrawer</em>. This collection descriptor references a foreign key with the
  +                    <code>field-ref="drawerId"</code>. This reference is to the anonymous field descriptor
  +                    in the Thing descriptor. The field-ref matches to the name in the descriptor whether or
  +                    not the name also maps to the Java attribute name. This dual use of
                       <code>name</code> can be confusing - be careful.
                   </p>
                   <p>
  -                    The same type mapping that is used for the collection descriptor in the Drawer descriptor is also used for the 1:1 reference descriptor in the Desk descriptor.
  +                    The same type mapping that is used for the collection descriptor in the Drawer descriptor
  +                    is also used for the 1:1 reference descriptor in the Desk descriptor.
                   </p>
                   <p>
  -                    The primary keys are populated into the objects as it is generally a good practice to not implement primary keys as anonymous access fields. Primary keys may be anonymous-access but references will get lost if the cache is cleared or the persistent object is serialized.
  +                    The primary keys are populated into the objects as it is generally a good practice to not
  +                    implement primary keys as anonymous access fields. Primary keys may be anonymous-access but
  +                    references will get lost if the cache is cleared or the persistent object is serialized.
                   </p>
               </section>
           </section>
  
  
  
  1.3       +44 -1     db-ojb/forrest/src/documentation/content/xdocs/docu/faq.xml
  
  Index: faq.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/forrest/src/documentation/content/xdocs/docu/faq.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- faq.xml	25 Apr 2004 01:31:33 -0000	1.2
  +++ faq.xml	26 Apr 2004 18:25:20 -0000	1.3
  @@ -888,6 +888,46 @@
               </answer>
           </faq>
   
  +        <faq id="lookupPB">
  +            <question>
  +                How to lookup <code>PersistenceBroker</code> instances?
  +            </question>
  +            <answer>
  +                <p>
  +                    The <code>org.apache.ojb.broker.PersistenceBrokerFactory</code> make several
  +                    methods available:
  +                </p>
  +                <source><![CDATA[
  +public PersistenceBroker createPersistenceBroker(PBKey key) throws PBFactoryException;
  +
  +public PersistenceBroker createPersistenceBroker(String jcdAlias, String user, String password)
  +        throws PBFactoryException;
  +
  +public PersistenceBroker defaultPersistenceBroker() throws PBFactoryException;
  +                ]]></source>
  +                <p>
  +                    Method <code>defaultPersistenceBroker()</code> can be used if the attribute
  +                    <link href="site:repository/jdbc-connection-descriptor"><em>default-connection</em></link>
  +                    is set <em>true</em> in <em>jdbc-connection-descriptor</em>. It's a convenience method,
  +                    useful when only one database is used.
  +                </p>
  +                <p>
  +                    The standard way to lookup a broker instance is via <code>org.apache.ojb.broker.PBKey</code>
  +                    by specify <em>jcdAlias</em> (specified in the
  +                    <link href="ext:repository-database">connection descriptor</link>), <em>user</em> and <em>passwd</em>. If the user and password is
  +                    already set in <em>jdbc-connection-descriptor</em> it is possible to lookup the broker
  +                    instance only be specify the <em>jcdAlias</em> in PBKey:
  +                </p>
  +                <source><![CDATA[
  +PBKey pbKey = new PBKey("myJcdAliasName");
  +PersistenceBroker broker = PersitenceBrokerFactory.createPersistenceBroker(pbKey);
  +                ]]></source>
  +                <p>
  +                    See <link href="#userPasswordNeeded">here too</link>.
  +                </p>
  +            </answer>
  +        </faq>
  +
           <faq id="userPasswordNeeded">
               <question>
                   Needed to put user/password of database connection in repository file?
  @@ -908,6 +948,9 @@
                       <link href="site:repository">repository file doc - section jdbc-connection-descriptor
                           <code>default-connection</code> attribute
                       </link>
  +                </p>
  +                <p>
  +                    See <link href="#lookupPB">here too</link>.
                   </p>
                   <source>
   PBKey pbKey = new PBKey(jcdAlias, user, passwd);
  
  
  
  1.2       +16 -3     db-ojb/forrest/src/documentation/content/xdocs/docu/pb-tutorial.xml
  
  Index: pb-tutorial.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/forrest/src/documentation/content/xdocs/docu/pb-tutorial.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- pb-tutorial.xml	23 Apr 2004 22:32:48 -0000	1.1
  +++ pb-tutorial.xml	26 Apr 2004 18:25:20 -0000	1.2
  @@ -130,7 +130,8 @@
                       instance of a
                       <code>PersistenceBroker</code> to the default data source. This is most
                       often how it is used if there is only one database for an application. If there
  -                    are multiple data sources, a broker may be obtained by name.
  +                    are multiple data sources, a broker may be obtained by name (using a <code>PBKey</code>
  +                    instance as argument in <code>PersistenceBrokerFactory.createPersistenceBroker(pbKey)</code>).
                   </p>
                   <p>
                       It is worth noting that the
  @@ -153,7 +154,19 @@
                       Once a
                       <code>PersistenceBroker</code> has been obtained, its
                       <code>PersistenceBroker.store(Object)</code> method is used to make an object
  -                    persistent. If several objects need to be stored, this can be done within
  +                    persistent.
  +                 </p>
  +                <p>
  +                    Maybe you have noticed that there has not been an assignment to
  +                    <code>product.id</code>, the primary-key attribute. Upon storing <code>product</code>
  +                    OJB detects that the attribute is not properly set and assigns a
  +                    unique id. This automatic assignment of unique Ids for the attribute
  +                    <code>id</code> has been explicitly declared in the
  +                    <link href="site:repository">XML repository</link> file, as we discussed in the
  +                    <link href="site:mapping-tutorial/metadata"></link>.
  +                </p>
  +                 <p>
  +                    If several objects need to be stored, this can be done within
                       a transaction, as follows.
                   </p>
                   <source><![CDATA[
  
  
  
  1.3       +19 -4     db-ojb/forrest/src/documentation/content/xdocs/docu/advanced-technique.xml
  
  Index: advanced-technique.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/forrest/src/documentation/content/xdocs/docu/advanced-technique.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- advanced-technique.xml	23 Apr 2004 19:17:46 -0000	1.2
  +++ advanced-technique.xml	26 Apr 2004 18:25:20 -0000	1.3
  @@ -681,7 +681,7 @@
   </class-descriptor>]]></source>
                   <p>
                       You can learn more about the anonymous fields feature in this
  -                    <link href="site:anonymous-keys">howto</link> and how
  +                    <link href="site:howto/anonymous-keys">howto</link> and how
                       it <link href="#anonymous-keys">work here</link>.
                   </p>
               </section>
  @@ -750,8 +750,23 @@
                   All involved classes can be found in <code>org.apache.ojb.broker.metadata.fieldaccess</code> package. The
                   classes used for <em>anonymous keys</em> start with a <code>AnonymousXYZ.java</code> prefix.
                   <br/>
  -TODO: ############ write this section ###########
  +                Main class used for provide anonymous keys is
  +                <code>org.apache.ojb.broker.metadata.fieldaccess.AnonymousPersistentField</code>. Current implementation
  +                use an object identity based weak HashMap. The persistent object identity is used as key for the
  +                anonymous key value. The (Anonymous)PersistentField instance is associated with the <em>FieldDescriptor</em>
  +                declared in the repository.
               </p>
  +            <p>
  +                This means that all anonymous key information will be lost when the object identity change, e.g. the
  +                persistent object will be de-/serialized or copied. In conjuction with 1:1 references this will be
  +                no problem, because OJB can use the referenced object to re-create the anonymous key information
  +                (FK to referenced object).
  +            </p>
  +            <warning>
  +                The use of anonymous keys in 1:n references (FK to main object) or for PK fields is only
  +                valid when object identity does not change, e.g. use in single JVM without persistent
  +                object serialization and without persistent object copying.
  +            </warning>
           </section>
   
   
  
  
  
  1.2       +5 -4      db-ojb/forrest/src/documentation/content/xdocs/docu/mapping-tutorial.xml
  
  Index: mapping-tutorial.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/forrest/src/documentation/content/xdocs/docu/mapping-tutorial.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- mapping-tutorial.xml	23 Apr 2004 19:17:46 -0000	1.1
  +++ mapping-tutorial.xml	26 Apr 2004 18:25:20 -0000	1.2
  @@ -19,7 +19,7 @@
   
   <document>
       <header>
  -        <title></title>
  +        <title>Mapping Tutorial</title>
           <authors>
               <person name="Brian McCallister" email="brian@skife.org"/>
           </authors>
  @@ -65,8 +65,8 @@
         private Integer id;
                     ]]></source>
                     <p>
  -                      Including the primary-key attribute in the class definition is optional,
  -                      <link href="site:howto/anonymous-keys">anonymous keys</link>
  +                      Including the primary-key attribute in the class definition is mandatory,
  +                      but under certain conditions <link href="site:howto/anonymous-keys">anonymous keys</link>
                         can also be used to keep this database artifact hidden in the database. However,
                         as access to an artifical unique identifier for a particular object instance can be
                         useful, particularly in web-based applications, this tutorial will expose it.
  @@ -98,6 +98,7 @@
                     </p>
                 </section>
                 <section><title>The Metadata</title>
  +                  <anchor id="metadata"/>
                     <p>
                         The <code>repository.xml</code> document is split into several physical documents.
                         The <code>repository_user.xml</code> xml file is used to contain user-defined
  
  
  
  1.2       +14 -5     db-ojb/forrest/src/documentation/content/xdocs/docu/testsuite.xml
  
  Index: testsuite.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/forrest/src/documentation/content/xdocs/docu/testsuite.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- testsuite.xml	25 Apr 2004 01:31:33 -0000	1.1
  +++ testsuite.xml	26 Apr 2004 18:25:20 -0000	1.2
  @@ -119,10 +119,12 @@
           <section>
               <title>What about known issues?</title>
               <p>
  -                All major known issues are listed in the <link href="ext:ojb/release-notes"></link>.
  -                The tests for open bugs will be skipped on released versions. It is possible to enable
  -                these tests to see failing test cases by set a flag in <code>[db-ojb]/build.properties</code>
  -                file:
  +                All major known issues are listed in the <link href="ext:ojb/release-notes">release-notes</link>
  +                file.
  +                <br/>
  +                The tests reproduce open bugs will be skipped on released OJB versions. It is possible to enable
  +                these tests to see all failing test cases of the shipped version by changing a
  +                flag in <code>[db-ojb]/build.properties</code> file:
               </p>
               <source><![CDATA[
   ###
  @@ -131,6 +133,13 @@
   # skipped. Default value is 'true'. For development 'false' is recommended,
   # because this will show unsolved problems.
   OJB.skip.issues=true]]></source>
  +        </section>
  +
  +        <section>
  +            <title>Donate own tests for OJB Test Suite</title>
  +            <p>
  +                Details about <link href="site:test-write">donate own test to OJB you can find here</link>.
  +            </p>
           </section>
       </body>
   </document>
  
  
  
  1.2       +152 -8    db-ojb/forrest/src/documentation/content/xdocs/docu/testwrite.xml
  
  Index: testwrite.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/forrest/src/documentation/content/xdocs/docu/testwrite.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- testwrite.xml	25 Apr 2004 01:31:33 -0000	1.1
  +++ testwrite.xml	26 Apr 2004 18:25:20 -0000	1.2
  @@ -19,7 +19,7 @@
   
   <document>
       <header>
  -        <title>Write Tests</title>
  +        <title>OJB - Write Tests</title>
           <authors>
               <person name="Armin Waibel" email="arminw@apache.org"/>
           </authors>
  @@ -28,18 +28,162 @@
       <body>
           <section>
               <title>Introduction</title>
  -            <fixme author="arminw">
  -            Write this document!
  -            </fixme>
               <p>
  -
  +                As described in
  +                <link href="site:test-suite">
  +                    <em>test suite</em> section
  +                </link> OJB
  +                emphasise quality assurance and provide a huge test suite. But it is impossible to cover
  +                all parts of OJB with tests and OJB will never be perfect (of course it's nearly perfect ;-)),
  +                thus if you miss a test or found an bug don't hesitate, write your own test and send it to
  +                <link href="site:mail-lists">the lists</link> or
  +                attach it in the
  +                <link href="site:bugs">bug report</link>.
               </p>
           </section>
  +
           <section>
  -            <title>Donate new Tests</title>
  +            <title>How to write a new Test</title>
               <p>
  -
  +                Before start writing your own test case please pay attention of these rules.
               </p>
  +
  +            <section>
  +                <title>The Test Class</title>
  +                <p>
  +                    All test classes have to inherit from
  +                    <code>org.apache.ojb.junit.OJBTestCase</code>
  +                    and have to provide a static main method to start the Junit test:
  +                </p>
  +                <source><![CDATA[
  +public class MyTest extends OJBTestCase
  +{
  +    public static void main(String[] args)
  +    {
  +        String[] arr = {MyTest.class.getName()};
  +        junit.textui.TestRunner.main(arr);
  +    }
  +
  +    public void testMyFirstOne()
  +    {
  +        ....
  +    {]]></source>
  +                <p>
  +                    In package
  +                    <code>org.apache.ojb.junit</code> can be found some test classes for specifc
  +                    circumstances:
  +                </p>
  +                <ul>
  +                    <li>
  +                        <code>org.apache.ojb.junit.PBTestCase</code> - Provide a public
  +                        <code>org.apache.ojb.broker.PersistenceBroker</code> field.
  +                    </li>
  +                    <li>
  +                        <code>org.apache.ojb.junit.ODMGTestCase</code> - Provide public
  +                        <code>org.odmg.Implementation</code> and
  +                        <code>org.odmg.Database</code> fields.
  +                    </li>
  +                    <li>
  +                        <code>org.apache.ojb.junit.JUnitExtensions</code> - Provide base classes for
  +                        write multithreaded test classes. More info see javadoc comment of this class.
  +                    </li>
  +                </ul>
  +                <p>
  +                    A test case for the PB-API may look like:
  +                </p>
  +                <source><![CDATA[
  +public class ReferenceRuntimeSettingTest extends PBTestCase
  +{
  +    public static void main(String[] args)
  +    {
  +        String[] arr = {ReferenceRuntimeSettingTest.class.getName()};
  +        junit.textui.TestRunner.main(arr);
  +    }
  +
  +    public void testChangeReferenceSetting()
  +    {
  +        ClassDescriptor cld = broker.getClassDescriptor(MainObject.class);
  +        // and so on
  +        ....
  +    }]]></source>
  +                <p>
  +                    The PersistenceBroker cleanup is done by
  +                    <em>PBTestCase</em>.
  +                </p>
  +            </section>
  +
  +            <section>
  +                <title>Persistent Objects used by Test</title>
  +                <p>
  +                    We recommend to introduce separate persistent objects for each TestCase class.
  +                    In <link href="site:test-suite">test suite</link> two concepts are used:
  +                </p>
  +                <ul>
  +                    <li>
  +                        Include your persistent objects as <em>public static classes</em> in your
  +                        test class.
  +                    </li>
  +                    <li>
  +                        Separate your test class in an independent package and include the test case and
  +                        all persistent object classes in this new package.
  +                    </li>
  +                </ul>
  +            </section>
  +
  +            <section>
  +                <title>Test Class Metadata</title>
  +                <p>
  +                    Currently all test specific object metadata (class-descriptor used for tests) are
  +                    shared among several xml files. The naming convention is <code>repository_junit_XXX.xml</code>.
  +                    Thus metadata for new tests should be included in one of the existing junit repository (sub)
  +                    files or writen in an new separate one and included in repository main file.
  +                </p>
  +                <source><![CDATA[
  +<!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 user SYSTEM "repository_user.xml">
  +
  +<!-- here the junit include files begin  -->
  +<!ENTITY junit SYSTEM "repository_junit.xml">
  +<!ENTITY junit_odmg SYSTEM "repository_junit_odmg.xml">
  +<!ENTITY junit_otm SYSTEM "repository_junit_otm.xml">
  +<!ENTITY junit_ref SYSTEM "repository_junit_reference.xml">
  +<!ENTITY junit_meta_seq SYSTEM "repository_junit_meta_seq.xml">
  +<!ENTITY junit_model SYSTEM "repository_junit_model.xml">
  +<!ENTITY junit_cloneable SYSTEM "repository_junit_cloneable.xml">
  +
  +<!ENTITY junit_myfirsttest SYSTEM "repository_junit_myfirsttest.xml">
  +]>
  +<descriptor-repository version="1.0" isolation-level="read-uncommitted"
  +        proxy-prefetching-limit="50">
  +
  +    <!-- include all used database connections -->
  +    &database;
  +
  +    <!-- include ojb internal mappings here -->
  +    &internal;
  +
  +    <!-- include user defined mappings here -->
  +    &user;
  +
  +    <!-- include mappings for JUnit tests -->
  +    <!-- This could be removed (with <!ENTITY entry),
  +         if junit test suite was not used
  +    -->
  +    &junit;
  +    &junit_odmg;
  +    &junit_otm;
  +    &junit_ref;
  +    &junit_meta_seq;
  +    &junit_model;
  +    &junit_cloneable;
  +
  +    &junit_myfirsttest;]]></source>
  +            </section>
           </section>
       </body>
   </document>
  
  
  
  1.1                  db-ojb/forrest/src/documentation/content/xdocs/docu/sequencemanager.xml
  
  Index: sequencemanager.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <!--
    Copyright 2002-2004 The Apache Software Foundation
  
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
  
        http://www.apache.org/licenses/LICENSE-2.0
  
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
  -->
  <!-- @version $Id: sequencemanager.xml,v 1.1 2004/04/26 18:25:20 arminw Exp $ -->
  <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.2//EN" "document-v12.dtd">
  
  <document>
      <header>
          <title>Sequence Manager</title>
          <authors>
              <person name="Armin Waibel" email="arminw@apache.org"/>
              <person name="Thomas Mahler" email="thma@apache.org"/>
              <person name="Ryan Vanderwerf et al." email=""/>
              <person name="Andrew Clute" email=""/>
          </authors>
      </header>
  
      <body>
          <section>
              <title>The OJB Sequence Manager</title>
              <p>
                  All sequence manager implementations you will find under the
                  <code>org.apache.ojb.broker.util.sequence</code> package using the following naming
                  convention
                  <code>SequenceManagerXXXImpl</code>.
              </p>
  
              <section>
                  <title>Automatical assignment of unique values</title>
                  <p>
                      As mentioned in
                      <link href="site:mapping-tutorial">mapping tutorial</link> OJB provides a mechanism to assign
                      unique values for primary key attributes. You just have to enable the
                      <code>autoincrement</code>
                      attribute in the respective
                      <link href="site:repository/field-descriptor">
                          <em>FieldDescriptor</em>
                      </link>
                      of the XML repository file as follows:
                  </p>
                  <source><![CDATA[
  <class-descriptor
    class="my.Article"
    table="ARTICLE"
  >
      <field-descriptor
       name="articleId"
       column="ARTICLE_ID"
       jdbc-type="INTEGER"
       primarykey="true"
       autoincrement="true"
      />
      ....
  </class-descriptor>]]></source>
                  <p>
                      This definitions contains the following information:
                      <br/>
                      The attribute
                      <code>articleId</code> is mapped on the table's
                      column
                      <code>ARTICLE_ID</code>. The JDBC Type of
                      this column is
                      <code>INTEGER</code>. This
                      is a primary key column. OJB shall automatically assign unique values
                      to this attribute.
                  </p>
  
                  <p>
                      This mechanism works for columns of type INTEGER, CHAR and
                      VARCHAR. This mechanism helps you to keep your business logic free
                      from code that computes unique Ids for primary key attributes.
                  </p>
              </section>
  
  
              <section>
                  <title>Force computation of unique values</title>
                  <p>
                      By default OJB triggers the computation
                      of unique ids during calls to PersistenceBroker.store(...).
                      Sometimes it will be necessary to have the ids computed in advance.
                      This can be done by simply obtaining the Identity of the respective object as
                      follows:
                  </p>
                  <source><![CDATA[
  Identity oid = new Identity(object, targetBroker);                 ]]></source>
                  <fixme author="arminw">
                      Fix when new Identity creation concept is implemented.
                  </fixme>
              </section>
  
  
              <section>
                  <title>How to change the sequence manager?</title>
                  <p>
                      To enable a specific
                      <code>SequenceManager</code> implementation declare
                      an
                      <code>sequence-manager</code> within the
                      <code>jdbc-connection-descriptor</code>
                      element in the
                      <link href="site:repository">repository file</link>.
                      If no
                      <code>sequence-manager</code> was specified in the
                      <code>jdbc-connection-descriptor</code>,
                      OJB use a default sequence manager implementation (default was
                      <em>SequenceManagerHighLowImpl</em>).
                  </p>
                  <p>
                      Further information you could find in the
                      <link href="ext:repository.dtd">repository.dtd</link> section sequence-manager element.
                  </p>
                  <p>
                      Example
                      <code>jdbc-connection-descriptor</code> using
                      <code>sequence-manager</code> tag:
                  </p>
                  <source><![CDATA[
  <jdbc-connection-descriptor
          jcd-alias="farAway"
          platform="Hsqldb"
          jdbc-level="2.0"
          driver="org.hsqldb.jdbcDriver"
          protocol="jdbc"
          subprotocol="hsqldb"
          dbalias="../OJB_FarAway"
          username="sa"
          password=""
          batch-mode="false"
      >
          <connection-pool
              maxActive="5"
              whenExhaustedAction="0"
              validationQuery="select count(*) from OJB_HL_SEQ"
          />
  
          <sequence-manager className="org.apache.ojb.broker.util.
                                      sequence.SequenceManagerHighLowImpl">
              <attribute attribute-name="grabSize" attribute-value="5"/>
              <attribute attribute-name="globalSequenceId"
                      attribute-value="false"/>
              <attribute attribute-name="globalSequenceStart"
                      attribute-value="10000"/>
          </sequence-manager>
  </jdbc-connection-descriptor>]]></source>
                  <p>
                      The mandatory
                      <code>className</code> attribute needs the full-qualified class name of the
                      desired sequence-manager implementation. If a implementation needs configuration
                      properties you pass them using
                      <code>attribute</code> tags with
                      <code>attribute-name</code> represents the property name and
                      <code>attribute-value</code>
                      the property value. Each sequence manager implementation shows all properties on
                      the according javadoc page.
                  </p>
              </section>
  
  
              <section>
                  <title>SequenceManager implementations</title>
                  <p>
                      Source code of all
                      <code>SequenceManager</code> implementations can be
                      found in
                      <code>org.apache.ojb.broker.util.sequence</code> package.
                      <br/>
                      If you still think something is missing you can just write your
                      <link href="#how-to-write">own</link>
                      sequence manager implementation.
                  </p>
  
                  <section>
                      <title>High/Low sequence manager</title>
                      <anchor id="high-low"/>
                      <p>
                          Per default OJB internally uses a High/Low algorithm based sequence manager
                          for the generation of unique ids, as described in
                          <link href="http://www.ambysoft.com/mappingObjects.html">
                              Mapping Objects To Relational Databases</link>.
                          <br/>
                          This implementation is called
                          <code>ojb.broker.util.sequence.SequenceManagerHighLowImpl</code>
                          and is able to generate IDs unique to a given object and
                          all extent objects declarated in the objects class descriptor.
                          <br/>
                          If you ask for an uid using an interface with several
                          implementor classes, or a baseclass with several subclasses the returned
                          uid have to be unique accross all tables representing objects of the
                          extent in question (more see
                          <link href="#extent-aware">here</link>).
                          <br/>
                          It's also possible to use this implementation in a
                          <em>global mode</em>, generate
                          global unique id's.
                      </p>
                      <source><![CDATA[
  <sequence-manager className=
      "org.apache.ojb.broker.util.sequence.SequenceManagerHighLowImpl">
  
      <attribute attribute-name="grabSize" attribute-value="20"/>
      <attribute attribute-name="globalSequenceId"
                                      attribute-value="false"/>
      <attribute attribute-name="globalSequenceStart"
                                      attribute-value="10000"/>
      <attribute attribute-name="autoNaming"
                                      attribute-value="true"/>
  </sequence-manager>]]></source>
                      <p>
                          With property
                          <code>grabSize</code> you set the size of the assigned ids
                          (default was 20).
                      </p>
  
                      <p>
                          If property
                          <code>globalSequenceId</code> was set
                          <code>true</code> you will
                          get global unique ids over all persistent objects. Default was
                          <code>false</code>.
                          <br/>
                          The attribute
                          <code>globalSequenceStart</code> define the start value of the
                          global id generation (default was 10000).
                      </p>
                      <p>
                          This sequence manager implementation supports user defined
                          <em>sequence-names</em>
                          to manage the sequences.
                          The attribute
                          <code>autoNaming</code> define if sequence names should be build
                          automatic if none found in
                          <code>field-descriptor</code>.
                          <br/>
                          If set 'true' OJB try to build a
                          sequence name automatic if none found in field-descriptor
                          and set this name as
                          <code>sequence-name</code>
                          in field-descriptor (see
                          <link href="#sequence-name">more</link>).
                          If set 'false' OJB throws an exception
                          if none sequence name was found in field-descriptor (default was 'true').
                      </p>
                      <p>
                          Limitations:
                          <br/>- do
                          <strong>not</strong> use in
                          <strong>managed environments</strong> when connections were enlisted
                          in running transactions, e.g. when using DataSources of an application server
                          <br/>- if set connection-pool attribute 'whenExhaustedAction' to 'block' (wait for
                          connection if connection-pool is exhausted), under heavy load this sequence manager
                          implementation can block application.
                          <br/>- superfluously to mention, do not use if other non-OJB applications insert objects too
                      </p>
                  </section>
  
  
                  <section>
                      <title>In-Memory sequence manager</title>
                      <anchor id="in-memory"/>
                      <p>
                          Another sequence manager implementation is a
                          <em>In-Memory</em> version
                          called
                          <code>ojb.broker.util.sequence.SequenceManagerInMemoryImpl</code>.
                          <br/>
                          Only the first time an uid was requested for a object,
                          the manager query the database for the max value of the target
                          column - all following request were performed in memory. This
                          implementation ditto generate unique ids across all
                          extents, using the same mechanism as the High/Low implementation.
                      </p>
                      <source><![CDATA[
  <sequence-manager className="org.apache.ojb.broker.util.
                                  sequence.SequenceManagerInMemoryImpl">
      <attribute attribute-name="autoNaming"
                                      attribute-value="true"/>
  </sequence-manager>]]></source>
                      <p>
                          For attribute
                          <code>autoNaming</code>
                          <link href="#high-low">see</link>
                      </p>
                      <p>
                          This sequence manager implementation supports user defined
                          <em>sequence-names</em>
                          to manage the sequences (see
                          <link href="#sequence-name">more</link>) or if not
                          set in
                          <code>field-descriptor</code> it is done automatic.
                      </p>
                      <p>
                          This is the fastest standard sequence manager implementation, but
                          has some Limitations:
                          <br/>- do not use in clustered environments
                          <br/>- superfluously to mention, do not use (or handle with care) if other non-OJB
                          applications insert objects too
                      </p>
                  </section>
  
  
                  <section>
                      <title>Database sequences based implementation</title>
                      <anchor id="database-sequences-based"/>
                      <p>
                          If your database support sequence key generation (e.g. Oracle, SAP DB, PostgreSQL)
                          you could use the
                          <code>SequenceManagerNextValImpl</code> implementation let
                          your database generate the requested ids.
                      </p>
                      <source><![CDATA[
  <sequence-manager className="org.apache.ojb.broker.util.
                                  sequence.SequenceManagerNextValImpl">
      <attribute attribute-name="autoNaming"
                                      attribute-value="true"/>
  </sequence-manager>]]></source>
                      <p>
                          Attribute
                          <code>autoNaming</code> default was 'true'. If set 'true' OJB try to build a
                          sequence name automatic if none found in field-descriptor
                          and set this generated name as
                          <code>sequence-name</code>
                          in field-descriptor.
                          <br/>
                          If set 'false' OJB throws an exception
                          if none sequence name was found in field-descriptor, ditto
                          OJB does NOT try to create a database sequence entry when
                          for given sequence name no database sequence could be found.
                      </p>
                      <anchor id="sequence-name"/>
                      <p>
                          When using this sequence manager it is possible
                          to define a
                          <strong>sequence-name</strong>
                          <code>field-descriptor</code> attribute
                          in the repository file for each autoincrement/pk field. If you don't
                          specify a sequence name, the sequence manager try to
                          build a extent-aware sequence name on its own - except you set attribute
                          <code>autoNaming</code> to 'false', then an exception will be thrown.
                          <br/>
                          Keep in mind that in this case you are responsible to be aware of extents.
                          Thus you have to use the same
                          <code>sequence-name</code> attribute value
                          for all extents, even if the extents were mapped to different database tables.
                          <br/>
                          See usage of the
                          <code>sequence-name</code> attribute:
                      </p>
                      <source><![CDATA[
  <class-descriptor
        class="org.apache.ojb.broker.sequence.SMDatabaseSequence"
        table="SM_TAB_DATABASE_SEQUENCE"
      >
          <field-descriptor
           name="seqId"
           column="SEQ_ID"
           jdbc-type="INTEGER"
           primarykey="true"
           autoincrement="true"
           sequence-name="TEST_SEQUENCE"
          />
  
          ....
      </class-descriptor>]]></source>
                      <p>
                          Limitations:
                          <br/>- none known
                      </p>
                  </section>
  
  
                  <section>
                      <title>Database sequences based high/low implementation</title>
                      <anchor id="high-low-sequences"/>
                      <p>
                          Based on the sequence manager implementation described above, but
                          use a high/low algorithm to avoid database access.
                      </p>
                      <source><![CDATA[
  <sequence-manager className="org.apache.ojb.broker.util.
                          sequence.SequenceManagerSeqHiLoImpl">
  <attribute attribute-name="grabSize" attribute-value="20"/>
  <attribute attribute-name="autoNaming"
                                  attribute-value="true"/>
  </sequence-manager>]]></source>
                      <p>
                          With the property
                          <code>grabSize</code> you set the size of the assigned ids.
                          For attribute
                          <code>autoNaming</code>
                          <link href="#database-sequences-based">see</link>.
                      </p>
                      <p>
                          This sequence manager implementation supports user defined
                          <em>sequence-names</em>
                          to manage the sequences (see
                          <link href="#sequence-name">more</link>) or if not
                          set in
                          <code>field-descriptor</code> it is done automatic.
                      </p>
                      <p>
                          Limitations:
                          <br/>- superfluously to mention, do not use (or handle with care) if other non-OJB
                          applications insert objects too
                      </p>
                  </section>
  
  
                  <section>
                      <title>Oracle-style sequencing</title>
                      <p>
                          (By Ryan Vanderwerf et al.) This solution will give those seeking an oracle-style sequence generator
                          a final answer (Identity columns really suck). If you are using multiple
                          application servers in your environment, and your database does not
                          support read locking like Microsoft SQL Server, this is the only
                          safe way to guarantee unique keys (HighLowSequenceManager WILL
                          give out duplicate keys, and corrupt your data).
                          <br/>
                          The
                          <code>SequenceManagerStoredProcedureImpl</code> implementation enabled database
                          sequence key generation in a
                          <em>Oracle-style</em> for all databases (e.g. MSSQL, MySQL, DB2, ...).
                          <br/>
                          First add a new table
                          <code>OJB_NEXTVAL_SEQ</code> to
                          your database.
                      </p>
                      <source><![CDATA[
  CREATE TABLE OJB_NEXTVAL_SEQ
  (
      SEQ_NAME    VARCHAR(150) NOT NULL,
      MAX_KEY     INTEGER,
      CONSTRAINT SYS_PK_OJB_NEXTVAL PRIMARY KEY(SEQ_NAME)
  )]]></source>
                      <p>
                          You will also need a stored procedure called
                          <code>ojb_nextval_proc</code>
                          that will take care of giving you a guaranteed unique
                          sequence number.
                          <br/>
                          Here is an example for the stored procedure you need to
                          use sequencing for MSSQL server:
                      </p>
                      <source><![CDATA[
  CREATE PROCEDURE OJB_NEXTVAL_PROC
  @SEQ_NAME varchar(150)
  AS
  declare @MAX_KEY BIGINT
  -- return an error if sequence does not exist
  -- so we will know if someone truncates the table
  set @MAX_KEY = 0
  
  UPDATE OJB_NEXTVAL_SEQ
  SET    @MAX_KEY = MAX_KEY = MAX_KEY + 1
  WHERE  SEQ_NAME = @SEQ_NAME
  
  if @MAX_KEY = 0
  select 1/0
  else
  select @MAX_KEY
  RETURN @MAX_KEY ]]></source>
                      <p>
                          You have to adapt this script if MSSQL was not used
                          (We are interested in scripts for other databases).
                          Last, enable this sequence manager implementation:
                      </p>
                      <source><![CDATA[
  <sequence-manager className="org.apache.ojb.broker.util.
                         sequence.SequenceManagerStoredProcedureImpl">
      <attribute attribute-name="autoNaming"
                                      attribute-value="true"/>
  </sequence-manager>]]></source>
                      <p>
                          For attribute
                          <link href="#high-low">
                              <em>autoNaming</em>
                              see
                          </link>.
                      </p>
                      <p>
                          This sequence manager implementation supports user defined
                          <em>sequence-names</em>
                          to manage the sequences (see
                          <link href="#sequence-name">more</link>) or if not
                          set in
                          <code>field-descriptor</code> it is done automatic.
                      </p>
                      <p>
                          Limitations:
                          <br/>- currently none known
                      </p>
                  </section>
  
  
                  <section>
                      <title>Microsoft SQL Server 'uniqueidentifier' type (GUID) sequencing</title>
                      <anchor id="mssql-guid"/>
                      <p>
                          For those users you are using SQL Server 7.0 and up, the uniqueidentifier
                          was introduced, and allows for your rows Primary Keys to be GUID's that are
                          guaranteed to be unique in time and space.
                      </p>
  
                      <p>
                          However, this type is different than the Identity field type, whereas there
                          is no way to programmatically retrieve the inserted value. Most
                          implementations when using the u.i. field type set a default value of
                          "newid()". The SequenceManagerMSSQLGuidImpl class manages this process for
                          you as if it was any normal generated sequence/identity field.
                      </p>
  
                      <p>
                          Assuming that your PK on your table is set to 'uniqueidentifier', your
                          field-description would be the same as using any other SequenceManager:
                      </p>
                      <source><![CDATA[
  <field-descriptor
           name="guid"
           column="document_file_guid"
           jdbc-type="VARCHAR"
           primarykey="true"
           autoincrement="true"
        />
                          ]]></source>
                      <p>
                          Note that the jdbc-type is a VARCHAR,  and thus the attribute (in this case
                          'guid') on your class should be a String (SQL Server does the conversion
                          from the String representation to the binary representation when
                          retrieved/set).
                      </p>
  
                      <p>
                          You also need to turn on the SequenceManager in your
                          jdbc-connection-descriptor like this:
                      </p>
                      <source><![CDATA[
  <sequence-manager
      className="org.apache.ojb.broker.util.sequence.SequenceManagerMSSQLGuidImpl"
  />
                          ]]></source>
                      <p>
                          Limitations:
                          <br/>-This will only work with SQL Server 7.0 and higher as the
                          uniqueidentifier type was not introduced until then.
                          <br/>This works well in situations where other applications might be updated the
                          database as well, because it guarantees (well, as much as Microsoft can
                          guarantee) that there will be no collisions between the Guids generated.
                      </p>
                  </section>
  
  
                  <section>
                      <title>Identity based sequence manager</title>
                      <anchor id="native"/>
                      <p>
                          This sequence manager implementation supports database Identity columns
                          (supported by MySQL, MsSQL, HSQL, ...). When using identity columns we have to do
                          a trick to make the sequence manager work.
                          <br/>
                          OJB identify each persistence capable object by a unique
                          ojb-Identity object. These ojb-Identity
                          objects were created using the sequence manager instance to
                          get UID's. Often these ojb-Identity objects were created before
                          the persistence capable object was written to database.
                          <br/>
                          When using Identity columns it is not possible to retrieve the next
                          valid UID before the object was written to database. As recently as
                          the real object was written to database, you can ask the DB for the last
                          generated UID. Thus in SequenceManagerNativeImpl we have to do a trick and use
                          a 'temporary' UID till the object was written to database.
                          <br/>
                          So, if it's possible try to avoid using Identity columns in your
                          database model. If not use this sequence manager implementation to
                          as a workaround for the Identity problem.
                      </p>
                      <p>
                          To enable this sequence manager implementation set in your
                          <code>jdbc-connection-descriptor</code>:
                      </p>
                      <source><![CDATA[
  <sequence-manager
      className="org.apache.ojb.broker.util.sequence.SequenceManagerNativeImpl">
  </sequence-manager>
                          ]]></source>
                      <p>
                          To declare the identity column in the repository.xml file add
                          <code>primarykey="true"</code>,
                          <code>autoincrement="true"</code> and
                          <code>access="readonly"</code> to the field-descriptor
                          for your table's primary key identity column.
                      </p>
                      <source><![CDATA[
  <field-descriptor
          name="identifier"
          column="NATIVE_ID"
          jdbc-type="BIGINT"
          primarykey="true"
          autoincrement="true"
          access="readonly"/>
                          ]]></source>
                      <p>
                          Limitations:
                          <br/>- The Identity columns have to
                          <strong>start with value >= 1</strong> and should
                          never be negative.
                          <br/>- Use of Identity columns is
                          <strong>not extent aware</strong> (This may change in further versions).
                          More info
                          <link href="#extent-aware">here</link>.
                      </p>
                  </section>
              </section>
  
  
              <section>
                  <title>How to write my own sequence manager?</title>
                  <anchor id="how-to-write"/>
                  <p>
                      Very easy to do, just write a implementation class of the
                      interface
                      <code>org.apache.ojb.broker.util.sequence.SequenceManager</code>.
                      OJB use a factory (
                      <code>SequenceManagerFactory</code>)
                      to obtain sequence manager instances.
                  </p>
  
                  <p>
                      This Factory can be configured to generate instances of your
                      specific implementation by adding a
                      <code>sequence-manager</code>
                      tag in the
                      <code>jdbc-connection-descriptor</code>.
                  </p>
                  <source><![CDATA[
  <sequence-manager className="my.SequenceManagerMYImpl">
  </sequence-manager>]]></source>
                  <p>
                      That's it!
                  </p>
  
                  <p>
                      If your sequence manager implementation was derived from
                      <code>org.apache.ojb.broker.util.sequence.AbstractSequenceManager</code>
                      it's easy to pass configuration properties to your implementation using
                      <code>attribute</code> tags.
                  </p>
                  <source><![CDATA[
  <sequence-manager className="my.SequenceManagerMYImpl">
  <attribute attribute-name="myProperty" attribute-value="test"/>
  </sequence-manager>]]></source>
                  <p>
                      With
                  </p>
                  <source><![CDATA[
  public String getConfigurationProperty(String key, String defaultValue)]]></source>
                  <p>
                      method get the properties in your implementation class.
                  </p>
  
                  <note>
                      Of course we interested in your solutions! If you have
                      implemented something interesting, just contact us.
                  </note>
  
              </section>
  
  
              <section>
                  <title>Questions</title>
  
                  <section>
                      <title>When using sequence-name attribute in field-descriptor?</title>
                      <anchor id="when-using"/>
                      <p>
                          Most
                          <code>SequenceManager</code> implementations based on sequence names.
                          If you want retain control of sequencing use your own
                          <code>sequence-name</code> attribute
                          in the
                          <code>field-descriptor</code>. In that case you are reponsible to use the same name
                          across extents (see more info about
                          <link href="site:advanced-technique/polymorphism">extents and polymorphism</link>).
                          Per default the sequence manager build its own
                          <em>extent aware</em> sequence name with an
                          simple algorithm
                          (see
                          <code>org.apache.ojb.broker.util.sequence.SequenceManagerHelper#buildSequenceName</code>)
                          if necessary.
                          <br/>
                          In most cases this should be sufficient. If you have a very complex data model and you
                          will do many metadata changes in the repository file in future, then it could be better
                          to explicit use
                          <code>sequence-names</code> in the
                          <code>field-descriptor</code>. See
                          more
                          <link href="#pitfalls">avoid pitfals</link>.
                      </p>
                  </section>
  
  
                  <section>
                      <title>What to hell does
                          <em>extent aware</em> mean?
                      </title>
                      <p>
                          Say we have a abstract base class
                          <code>Animal</code> and two classes
                          <code>Dog</code> and
                          <code>Cat</code>
                          which extend
                          <code>Animal</code>. For each non-abstract class we create a separate
                          database table.
                          <br/>
                          We will be able to do a query like
                          <em>give me all animals</em>. Thus
                          the uid's of
                          <code>Dog</code> and
                          <code>Cat</code>  objects must be unique across the
                          tables of both classes or else you may not get a vaild query result.
                          <br/>
                          The reason for this behaviour is the
                          <code>org.apache.ojb.broker.Identity</code>
                          class implementation (this may change in further versions).
                      </p>
                  </section>
  
  
                  <section>
                      <title>How could I prevent auto-build of the sequence-name?</title>
                      <anchor id="no-auto-build"/>
                      <p>
                          All shipped
                          <code>SequenceManager</code> implementations which using sequence names
                          for UID generation, support by default auto-build (autoNaming) of the sequence name
                          if none was found in the
                          <code>field-descriptor</code>.
                          <br/>
                          To prevent this, all relevant SM implementations support a
                          <code>autoNaming</code>
                          property - set via
                          <code>attribute</code> element. If set
                          <code>false</code> OJB doesn't
                          try to build sequence names automatic.
                          </p>
  <source><![CDATA[
  <sequence-manager className="XYZ">
  ...
      <attribute attribute-name="autoNaming" attribute-value="true"/>
  ...
  </sequence-manager>]]></source>
                  </section>
  
                  <section>
                      <title>Sequence manager handling using multiple databases</title>
                      <anchor id="sequenceManagerHandling"/>
                      <p>
                          If you use multiple databases you have to declare a sequence manager in each
                          <code>jdbc-connection-descriptor</code>. If you don't specify a sequence manager
                          OJB use the default one (currently
                          <code>ojb.broker.util.sequence.SequenceManagerHighLowImpl</code>).
                      </p>
                  </section>
  
                  <section>
                      <title>One sequence manager with multiple databases?</title>
                      <anchor id="oneSequenceManager"/>
                      <p>
                          OJB was intended to use a sequence manager per database. But it
                          shouldn't be complicated to realize a global sequence manager
                          solution by writing your own
                          <code>SequenceManager</code> implementation.
                      </p>
                  </section>
  
  
                  <section>
                      <title>Can I get direct access to the sequence manager?</title>
                      <anchor id="directAccess"/>
                      <p>
                          That's no problem:
                      </p>
                      <source><![CDATA[
                      PersistenceBroker broker =
                      PersistenceBrokerFactory.createPersistenceBroker(myPBKey);
                      SequenceManager sm = broker.serviceSequenceManager();
                      ...
                      broker.close();]]></source>
                      <p>
                          If you use
                          <code>autoincrement=true</code> in your
                          <code>field-descriptor</code>,
                          there is no reason to obtain UID directly from the sequence manager or to handle
                          UID in your object model.
                          <br/>
                          [NOTE: Don't use SequenceManagerFactory#getSequenceManager(PersistenceBroker broker), this
                          method returns a new sequence manager instance for the given broker instance and not the current
                          used SM instance of the given PersistenceBroker instance]
                      </p>
                  </section>
  
  
                  <section>
                      <title>Any known pitfalls?</title>
                      <anchor id="pitfalls"/>
                      <ul>
                          <li>
                              When enable a sequence manager implementation based on
                              <em>sequence-name</em> attributes
                              and if the name was not set as an attribute in the
                              <code>field-descriptor</code>
                              (
                              <link href="#sequence-name">see</link>), an simple algorithm was used to build the
                              sequence name.
                              <br/>
                              The algorithm try to get the top-level class of the field's enclosing class,
                              if no top-level class was found, the table name of the field's enclosing class was used.
                              If a top-level class was found, the first found extent class table name was used as sequence name.
                              <br/>
                              When using base classes/interfaces with extent classes based on different database tables
                              and the
                              <code>extent-class</code> entries in repository often change, the algorithm could be
                              corrupted, because the first found extent class's table name could be change.
                              <br/>
                              To avoid this, remove the implementation internal sequence name entry (e.g. OJB_HL_SEQ table
                              entry when using the Hi/Lo implementation, or remove the database sequence entry when using
                              the 'Nextval' implementation) in that case, or use custom sequence name attributes in the
                              field descriptor.
                          </li>
                      </ul>
                  </section>
              </section>
          </section>
      </body>
  </document>
  
  
  
  1.4       +6 -4      db-ojb/forrest/src/documentation/content/xdocs/site.xml
  
  Index: site.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/forrest/src/documentation/content/xdocs/site.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- site.xml	25 Apr 2004 01:31:33 -0000	1.3
  +++ site.xml	26 Apr 2004 18:25:21 -0000	1.4
  @@ -75,7 +75,9 @@
           </start>
   
           <tutorials label="Tutorials">
  -            <mapping-tutorial label="Mapping Tutorial" href="mapping-tutorial.html" description="Mapping tutorial"/>
  +            <mapping-tutorial label="Mapping Tutorial" href="mapping-tutorial.html" description="Mapping tutorial">
  +                <metadata href="#metadata"/>
  +            </mapping-tutorial>
               <pb-tutorial label="The PB API" href="pb-tutorial.html" description="PB tutorial"/>
               <odmg-tutorial label="The ODMG API" href="odmg-tutorial.html" description="odmg tutorial"/>
               <jdo-tutorial label="The JDO API" href="jdo-tutorial.html" description="jdo tutorial"/>
  @@ -139,7 +141,7 @@
   
           <howto label="Howto's">
               <large-metadata label="Build large Metadata Mappings" href="howto-build-mappings.html" description=""/>
  -            <anonymous-keys label="Using anonymous keys" href="howto-use-anonymous-keys.html" description=""/>
  +            <anonymous-keys label="Anonymous Keys" href="howto-use-anonymous-keys.html" description=""/>
               <db-sequences label="Using database sequences" href="howto-use-db-sequences.html" description=""/>
               <use-lobs label="Use Oracle LOB's" href="howto-use-lobs.html" description=""/>
               <clustering label="Work in clustered environment" href="howto-work-with-clustering.html" description=""/>
  @@ -147,7 +149,7 @@
           </howto>
           <testing label="Testing">
               <test-suite label="Test Suite" href="testsuite.html"/>
  -            <write-test label="Write Tests" href="testwrite.html"/>
  +            <test-write label="Write Tests" href="testwrite.html"/>
           </testing>
       </documentation>
   
  
  
  

---------------------------------------------------------------------
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