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 to...@apache.org on 2004/05/09 15:50:30 UTC

cvs commit: db-ojb/forrest/src/documentation/content/xdocs/docu advanced-technique.xml basic-technique.xml

tomdz       2004/05/09 06:50:30

  Modified:    forrest/src/documentation/content/xdocs site.xml
               forrest/src/documentation/content/xdocs/docu
                        advanced-technique.xml basic-technique.xml
  Log:
  Added section about using mapping interfaces
  
  Revision  Changes    Path
  1.11      +5 -2      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.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- site.xml	9 May 2004 11:08:08 -0000	1.10
  +++ site.xml	9 May 2004 13:50:29 -0000	1.11
  @@ -109,11 +109,14 @@
                   <cascading href="#cascading"/>
                   <auto-retrieve href="#auto-retrieve"/>
                   <using-proxy href="#using-proxy"/>
  -                <single-proxy href="#single-proxy"/>
  +                <collection-proxy href="#collection-proxy"/>
  +                <reference-proxy href="#reference-proxy"/>
  +                <proxy-customization href="#proxy-customization"/>
               </basic-technique>
               <advanced-technique label="Advanced Technique" href="advanced-technique.html" description="">
                   <anonymous-keys href="#anonymous-keys"/>
                   <polymorphism href="#polymorhism"/>
  +                <interfaces href="#interfaces"/>
                   <using-rowreader href="#using-rowreader"/>
                   <rowreader-example href="#rowreader-example"/>
                   <nested-objects href="#nested-objects"/>
  
  
  
  1.6       +252 -1    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.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- advanced-technique.xml	28 Apr 2004 08:03:52 -0000	1.5
  +++ advanced-technique.xml	9 May 2004 13:50:29 -0000	1.6
  @@ -687,6 +687,257 @@
               </section>
           </section>
   
  +        <anchor id="interfaces"/>
  +        <section>
  +            <title>Using interfaces with OJB</title>
  +            <p>
  +                Sometimes you may want to declare class descriptors for interfaces rather
  +                than for concrete classes. With OJB this is no problem, but there are a
  +                couple of things to be aware of, which are detailed in this section.
  +            </p>
  +            <p>
  +                Consider this example hierarchy :
  +            </p>
  +                <source><![CDATA[
  +public interface A
  +{
  +    String getDesc();
  +}
  +
  +public class B implements A
  +{
  +    /** primary key */
  +    private Integer id;
  +    /** sample attribute */
  +    private String desc;
  +
  +    public String getDesc()
  +    {
  +        return desc;
  +    }
  +    public void setDesc(String desc)
  +    {
  +        this.desc = desc;
  +    }
  +}
  +
  +public class C
  +{
  +    /** primary key */
  +    private Integer id;
  +    /** foreign key */
  +    private Integer aId;
  +    /** reference */
  +    private A obj;
  +
  +    public void test()
  +    {
  +        String desc = obj.getDesc();
  +    }
  +}]]></source>
  +            <p>
  +                Here, class <code>C</code> references the interface <code>A</code> rather than <code>B</code>.
  +                In order to make this work with OJB, four things must be done:
  +            </p>
  +            <ul>
  +                <li>All features common to all implementations of <code>A</code> are declared in the
  +                    class descriptor of <code>A</code>. This includes references (with their foreignkeys)
  +                    and collections.</li>
  +                <li>Since interfaces cannot have instance fields, it is necessary to use bean properties instead.
  +                    This means that for every field (including collection fields), there must be accessors
  +                    (a get method and, if the field is not marked as <code>access="readonly"</code>, a set
  +                    method) declared in the interface.</li>
  +                <li>Since we're using bean properties, the appropriate
  +                    <code>org.apache.ojb.broker.metadata.fieldaccess.PersistentField</code>
  +                    implementation must be used (see <link href="#persistent-field">below</link>).
  +                    This class is used by OJB to access the fields when storing/loading objects. Per default,
  +                    OJB uses a direct access implementation
  +                    (<code>org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldDirectAccessImpl</code>) which
  +                    requires actual fields to be present.<br/>
  +                    In our case, we need an implementation that rather uses the accessor methods. Since the
  +                    <code>PersistentField</code> setting is (currently) global, you have to check whether
  +                    there are accessors defined for every field in the metadata. If yes, then you can use the
  +                    <code>org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldIntrospectorImpl</code>,
  +                    otherwise you'll have to resort to the
  +                    <code>org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldAutoProxyImpl</code>, which
  +                    determines for every field what type of field it is and then uses the appropriate
  +                    strategy.</li>
  +                <li>If at some place OJB has to create an object of the interface, say as the result type of
  +                    a query, then you have to specify <code>factory-class</code> and <code>factory-method</code>
  +                    for the interface. OJB then uses the specified class and (static) method to create an
  +                    uninitialized instance of the interface.</li>
  +            </ul>
  +            <p>
  +                In our example, this would result in:
  +            </p>
  +                <source><![CDATA[
  +public interface A
  +{
  +    void setId(Integer id);
  +    Integer getId();
  +    void setDesc(String desc);
  +    String getDesc();
  +}
  +
  +public class B implements A
  +{
  +    /** primary key */
  +    private Integer id;
  +    /** sample attribute */
  +    private String desc;
  +
  +    public String getId()
  +    {
  +        return id;
  +    }
  +    public void setId(Integer id)
  +    {
  +        this.id = id;
  +    }
  +    public String getDesc()
  +    {
  +        return desc;
  +    }
  +    public void setDesc(String desc)
  +    {
  +        this.desc = desc;
  +    }
  +}
  +
  +public class C
  +{
  +    /** primary key */
  +    private Integer id;
  +    /** foreign key */
  +    private Integer aId;
  +    /** reference */
  +    private A obj;
  +
  +    public void test()
  +    {
  +        String desc = obj.getDesc();
  +    }
  +}
  +
  +public class AFactory
  +{
  +    public static A createA()
  +    {
  +        return new B();
  +    }
  +}]]></source>
  +            <p>
  +                The class descriptors would look like:
  +            </p>
  +                <source><![CDATA[
  +<class-descriptor
  +    class="A"
  +    table="A_TABLE"
  +    factory-class="AFactory"
  +    factory-method="createA"
  +>
  +    <extent-class class-ref="B"/>
  +    <field-descriptor
  +        name="id"
  +        column="ID"
  +        jdbc-type="INTEGER"
  +        primarykey="true"
  +        autoincrement="true"
  +    />
  +    <field-descriptor
  +        name="desc"
  +        column="DESC"
  +        jdbc-type="VARCHAR"
  +        length="100"
  +    />
  +</class-descriptor>
  +
  +<class-descriptor
  +    class="B"
  +    table="B_TABLE"
  +>
  +    <field-descriptor
  +        name="id"
  +        column="ID"
  +        jdbc-type="INTEGER"
  +        primarykey="true"
  +        autoincrement="true"
  +    />
  +    <field-descriptor
  +        name="desc"
  +        column="DESC"
  +        jdbc-type="VARCHAR"
  +        length="100"
  +    />
  +</class-descriptor>
  +
  +<class-descriptor
  +    class="C"
  +    table="C_TABLE"
  +>
  +    <field-descriptor
  +        name="id"
  +        column="ID"
  +        jdbc-type="INTEGER"
  +        primarykey="true"
  +        autoincrement="true"
  +    />
  +    <field-descriptor
  +        name="aId"
  +        column="A_ID"
  +        jdbc-type="INTEGER"
  +    />
  +    <reference-descriptor name="obj"
  +        class-ref="A">
  +        <foreignkey field-ref="aId" />
  +    </reference-descriptor>
  +</class-descriptor>
  +]]></source>
  +            <p>
  +                One scenario where you might run into problems is the use of interfaces for
  +                <link href="#nested-objects">nested objects</link>. In the above example, we could
  +                construct such a scenario if we remove the descriptors for <code>A</code> and
  +                <code>B</code>, as well as the foreign key field <code>aId</code> from
  +                class <code>C</code> and change its class descriptor to:
  +            </p>
  +                <source><![CDATA[
  +<class-descriptor
  +    class="C"
  +    table="C_TABLE"
  +>
  +    <field-descriptor
  +        name="id"
  +        column="ID"
  +        jdbc-type="INTEGER"
  +        primarykey="true"
  +        autoincrement="true"
  +    />
  +    <field-descriptor
  +        name="obj::desc"
  +        column="DESC"
  +        jdbc-type="VARCHAR"
  +        length="100"
  +    />
  +</class-descriptor>
  +]]></source>
  +            <p>
  +                The access to <code>desc</code> will work because of the usage of bean properties,
  +                but you will get into trouble when using 
  +                <link href="site:basic-technique/dynamic-proxy">dynamic proxies</link> for <code>C</code>.
  +                Upon materializing an object of type <code>C</code>, OJB will try to create
  +                the instance for the field <code>obj</code> which is of type <code>A</code>.
  +                Of course, this is an interface but OJB won't check whether there is class
  +                descriptor for the type of <code>obj</code> (in fact there does not have to
  +                be one, and usually there isn't) because <code>obj</code> is not defined as
  +                a reference. As a result, OJB tries to instantiate an interface, which of
  +                course fails.<br/>
  +                Currently, the only way to handle this is to write a 
  +                <link href="site:basic-technique/proxy-customization">custom invocation handler</link>
  +                that knows how to create an object of type <code>A</code>.
  +            </p>
  +        </section>
  +
  +
           <anchor id="persistent-field"/>
           <section>
               <title>Change PersistentField Class</title>
  
  
  
  1.6       +2 -2      db-ojb/forrest/src/documentation/content/xdocs/docu/basic-technique.xml
  
  Index: basic-technique.xml
  ===================================================================
  RCS file: /home/cvs/db-ojb/forrest/src/documentation/content/xdocs/docu/basic-technique.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- basic-technique.xml	9 May 2004 11:10:07 -0000	1.5
  +++ basic-technique.xml	9 May 2004 13:50:30 -0000	1.6
  @@ -426,7 +426,7 @@
               </ul>
               <p>
                   Further down a third solution
  -                <link href="#single-proxy">using a single proxy for a whole collection</link> will be
  +                <link href="#collection-proxy">using a single proxy for a whole collection</link> will be
                   presented to circumvent the described drawbacks.
               </p>
   
  
  
  

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