You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by br...@apache.org on 2004/03/02 21:30:50 UTC

cvs commit: db-ojb/xdocs howto-use-anonymous-keys.xml

brianm      2004/03/02 12:30:50

  Modified:    xdocs    howto-use-anonymous-keys.xml
  Log:
  Made primary key's no longer anonymous access in the howto -- this leads to problems
  
  Revision  Changes    Path
  1.4       +76 -72    db-ojb/xdocs/howto-use-anonymous-keys.xml
  
  Index: howto-use-anonymous-keys.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/xdocs/howto-use-anonymous-keys.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- howto-use-anonymous-keys.xml	31 Aug 2003 00:01:17 -0000	1.3
  +++ howto-use-anonymous-keys.xml	2 Mar 2004 20:30:50 -0000	1.4
  @@ -1,52 +1,54 @@
   <?xml version="1.0"?>
   <document>
   
  -  <properties>
  -    <author email="brian@skife.org">Brian McCallister</author>
  -    <title>ObJectRelationalBridge - HOWTO Use Anonymous Keys</title>
  -  </properties>
  -
  -<body>
  -
  -<section name="HOWTO Use Anonymous Keys">
  -	<subsection name="Why Do We Need Anonymous Keys?">
  -		<p>
  -		The core difference between referential integrity in Java and in an RDBMS lies in where the specific referential information is maintained. Java, and most modern OO languages, maintain referential integrity information in the runtime environment. Actual object relationships are maintained by the virtual machine so that the symbolic variable used in the application is dereferenced it will in fact provide access to the object instance which it is expected to provide access to. There is no need for a manual lookup or search across the heap for the correct object instance. Entity reference integrity is maintained and handled for the programmer by the environment.
  -		</p>
  -		<p>
  -		Relational databases, on the other, purposefully place the referential integrity and lookups into the problem domain - that is the problem they are designed to solve. An RDBMS presumes you can design somehtign more efficient for your specific circumstances than the JVM does (you trust its ability to do object lookups in the heap is sufficiently efficient). As an RDBMS has a much larger heap equivalent, it is designed to not operate under that assumption (mostly). So, in an RDBMS the concept of specific foreign keys exists to maintain the referential integrity.
  -		</p>
  -		<p>
  -		In crossing the object to relational entity barrier there is a mismatch between the referential integrity implementations. Java programers do not want to have to maintain both object referential integrity and key referential integrity analogous to
  -		</p>
  -		<source><![CDATA[
  +    <properties>
  +        <author email="brianm@apache.org">Brian McCallister</author>
  +        <title>ObJectRelationalBridge - HOWTO Use Anonymous Keys</title>
  +    </properties>
  +
  +    <body>
  +
  +        <section name="HOWTO Use Anonymous Keys">
  +            <subsection name="Why Do We Need Anonymous Keys?">
  +                <p>
  +		The core difference between referential integrity in Java and in an RDBMS lies in where the specific
  +        referential information is maintained. Java, and most modern OO languages, maintain referential integrity information in the runtime environment. Actual object relationships are maintained by the virtual machine so that the symbolic variable used in the application is dereferenced it will in fact provide access to the object instance which it is expected to provide access to. There is no need for a manual lookup or search across the heap for the correct object instance. Entity reference integrity is maintained and handled for the programmer by the environment.
  +                </p>
  +                <p>
  +		Relational databases, on the other, purposefully place the referential integrity and lookups into the problem domain - that is the problem they are designed to solve. An RDBMS presumes you can design something more efficient for your specific circumstances than the JVM does (you trust its ability to do object lookups in the heap is sufficiently efficient). As an RDBMS has a much larger heap equivalent it is designed to not operate under that assumption (mostly). So, in an RDBMS the concept of specific foreign keys exists to maintain the referential integrity.
  +                </p>
  +                <p>
  +		In crossing the object to relational entity barrier there is a mismatch between the referential integrity implementations. Java programmers do not want to have to maintain both object referential integrity and key referential integrity analogous to
  +                </p>
  +                <source><![CDATA[
   {
       Foo parent = new SomeFooType();
       Foo child = new SomeOtherFooType();
       parent.addChild(child);
       child.setParentId(parent.getId());
   }
  -		]]></source>
  -		<p>
  +                ]]></source>
  +                <p>
   		This is double the work required - you set up the object relationship, then set up the key relationship.
  -		</p>
  -		<p>
  +                </p>
  +                <p>
   		OJB can provide transparent key relationship maintenance behind the scenes via anonymous access fields. 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.
  -		</p>
  -	</subsection>
  -</section>
  -<section name="Using Anonymous Keys">
  -	<subsection name="The Code">
  -		<p>
  +                </p>
  +            </subsection>
  +        </section>
  +        <section name="Using Anonymous Keys">
  +            <subsection name="The Code">
  +                <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.
  -		</p>
  -		<source><![CDATA[
  +                </p>
  +                <source><![CDATA[
   public class Desk
   {
       private Finish finish;
       /** Contains Drawer instances */
       private List drawers;
       private int numberOfLegs;
  +    private Integer id;
   
       public Desk()
       {
  @@ -84,6 +86,7 @@
   {
       /** Contains Thing instances */
       private List stuffInDrawer;
  +    private Integer id;
   
       public List getStuffInDrawer()
       {
  @@ -101,6 +104,7 @@
   {
       private String wood;
       private String color;
  +    private Integer id;
   
       public String getWood()
       {
  @@ -126,6 +130,7 @@
   public class Thing
   {
       private String name;
  +    private Integer id;
   
       public String getName()
       {
  @@ -137,16 +142,16 @@
           this.name = name;
       }
   }
  -		]]></source>
  -		<p>
  +                ]]></source>
  +                <p>
   		A Desk will typically reference multiple drawers and one finish.
  -		</p>
  -	</subsection>
  -	<subsection name="The Database">
  -		<p>
  +                </p>
  +            </subsection>
  +            <subsection name="The Database">
  +                <p>
   		When we need to store our instances in a database we use a fairly typical table per class persistance model.
  -		</p>
  -		<source><![CDATA[
  +                </p>
  +                <source><![CDATA[
   CREATE TABLE finish
   (
       id          INTEGER PRIMARY KEY,
  @@ -176,19 +181,20 @@
       drawer_id   INTEGER,
       FOREIGN KEY (drawer_id) REFERENCES drawer(id)
   );
  -		]]></source>
  -        <p>
  +                ]]></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).
  -        </p>
  -	</subsection>
  -	<subsection name="The Repository Configuration">
  -        <p>
  +                </p>
  +            </subsection>
  +            <subsection name="The Repository Configuration">
  +                <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.
  -        </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 <code>access="anonymous"</code> attribute.
  -        </p>
  -        <source><![CDATA[
  +                </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
  +                    <code>access="anonymous"</code> attribute.
  +                </p>
  +                <source><![CDATA[
   <class-descriptor
       class="Desk"
       table="desk">
  @@ -199,7 +205,6 @@
           jdbc-type="INTEGER"
           primarykey="true"
           autoincrement="true"
  -        access="anonymous"
           />
       <field-descriptor
           name="numberOfLegs"
  @@ -236,7 +241,6 @@
           jdbc-type="INTEGER"
           primarykey="true"
           autoincrement="true"
  -        access="anonymous"
           />
       <field-descriptor
           name="wood"
  @@ -262,7 +266,6 @@
           jdbc-type="INTEGER"
           primarykey="true"
           autoincrement="true"
  -        access="anonymous"
           />
       <field-descriptor
           name="deskId"
  @@ -288,7 +291,6 @@
           jdbc-type="INTEGER"
           primarykey="true"
           autoincrement="true"
  -        access="anonymous"
           />
       <field-descriptor
           name="name"
  @@ -303,26 +305,28 @@
           access="anonymous"
           />
   </class-descriptor>
  -        ]]></source>
  -        <p>
  +                ]]></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.
  -        </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 <code>name</code> can be confusing - be careful.
  -        </p>
  -        <p>
  +                </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
  +                    <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.
  -        </p>
  -	</subsection>
  -    <subsection name="Benefits and Drawbacks">
  -        <p>
  +                </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.
  +                </p>
  +            </subsection>
  +            <subsection name="Benefits and Drawbacks">
  +                <p>
           There are both benefits and drawbacks to using anonymous field references for maintaining referential integrity between Java objects and database relations. The most immediate benefit is avoiding semantic code duplication. The second major benefit is avoiding cluttering class definitions with persistance mechanism artifacts. In a well layered application, the persistance mechanism will not really need to be so obvious in the object model implementation. Anonymous fields helpt o achieve this - thereby making persistence mechanisms more flexible. Moving to a different one becomes easier.
  -        </p>
  -        <p>
  -        There is an indirect benefit to populating the various id type keys though, particularly in web based applications where yet another layer boundary must be crossed - to an html or html-form format where object references are again lost. If unique ids are not part of a class, they will wind up being regenerated at the object level for crossing to the next layer. While this might be a better method to a layer purist, it is considerably less efficient.
  -        </p>
  -    </subsection>
  -</section>
  -</body>
  +                </p>
  +            </subsection>
  +        </section>
  +    </body>
   </document>
   
  
  
  

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