arminw 2005/12/16 17:39:41
Modified: src/doc/forrest/src/documentation/content/xdocs/docu/guides
Tag: OJB_1_0_RELEASE advanced-technique.xml
src/doc/forrest/src/documentation/content/xdocs Tag:
OJB_1_0_RELEASE site.xml
Log:
update mapping part
Revision Changes Path
No revision
No revision
1.1.2.8 +159 -94
db-ojb/src/doc/forrest/src/documentation/content/xdocs/docu/guides/advanced-technique.xml
Index: advanced-technique.xml
===================================================================
RCS file:
/home/cvs/db-ojb/src/doc/forrest/src/documentation/content/xdocs/docu/guides/advanced-technique.xml,v
retrieving revision 1.1.2.7
retrieving revision 1.1.2.8
diff -u -r1.1.2.7 -r1.1.2.8
--- advanced-technique.xml 16 Dec 2005 20:55:48 -0000 1.1.2.7
+++ advanced-technique.xml 17 Dec 2005 01:39:41 -0000 1.1.2.8
@@ -310,86 +310,168 @@
only one special situation that needs some attention:
</p>
<p>
- Say there is a baseclass AB with derived classes A and
B. A and B
- are mapped on a table AB_TABLE. Storing A and B objects
to this table
+ Say there is a baseclass <code>AB</code> with derived
classes <code>B</code> and <code>B1</code>.
+ B and B1 are mapped on a table <em>AB_TABLE</em>.
Storing B and B1 objects to this table
works fine. But now consider a Query against the
baseclass AB. How
can the correct type of the stored objects be determined?
</p>
<p>
- OJB needs a column of type CHAR or VARCHAR that contains
the classname to
- be used for instantiation. This column must be mapped on
a special
- attribute
- <code>ojbConcreteClass</code>. On
- loading objects from the table OJB checks this attribute
and
- instantiates objects of this type.
- </p>
- <note>The criterion for
- <code>ojbConcreteClass</code> is statically added to the
- query in class
- <code>QueryFactory</code> and it therefore appears in
- the select-statement for each extent. This means that
mixing mapping strategies should be avoided.
+ OJB needs a <em>discriminator column</em> of type CHAR
or VARCHAR that contains the
+ classname to be used for instantiation. This column must
be mapped on a special
+ attribute <code>ojbConcreteClass</code>. On loading
objects from the table OJB
+ checks this attribute and instantiates objects of this
type.
+ </p>
+ <note>
+ The criterion for <code>ojbConcreteClass</code> is
statically added to the
+ query in class <a
href="ext:api/query-factory"><code>QueryFactory</code></a> and it
+ therefore appears in the select-statement for each
extent. This means that
+ mixing mapping strategies should be avoided.
</note>
<p>
There is sample code for this feature in the method
<code>org.apache.ojb.broker.PersistenceBrokerTest.testMappingToOneTable().</code>
- See the mapping details in the following Class
- declaration and the respective mapping:
+ See the mapping details in the following
+ <a href="site:class-descriptor">class declaration</a>
and the
+ <a href="site:repository">respective mapping</a> (all
classes are static inner classes of
+ class <code>ObjectRepository</code>, this is only for
test purpose - ignore this):
</p>
<source><![CDATA[
-public abstract class AB
+public static abstract class AB implements Serializable
{
- /** the special attribute telling OJB the object's concrete type.
- * NOTE: this attribute MUST be called ojbConcreteClass
+ private int id;
+ /**
+ * This special attribute telling OJB which concrete class
+ * this Object has.
+ * NOTE: this attribute MUST be called ojbConcreteClass
*/
- protected String ojbConcreteClass;
+ private String ojbConcreteClass;
+
+ protected AB()
+ {
+ // this guarantee that always the correct class name will be set
+ this.ojbConcreteClass = this.getClass().getName();
+ }
+ protected AB(int id)
+ {
+ this();
+ this.id = id;
+ }
+....
+// getter/setter for id and ojbConcreteClass
}
-public class A extends AB
+public static class B extends AB
{
- int id;
- int someValue;
+ private int someValue;
+ private String someBField;
- public A()
+ public B()
{
- // OJB must know the type of this object
- ojbConcreteClass = A.class.getName();
+ super();
}
+
+ public B(int pId, int pSomeValue)
+ {
+ super(pId);
+ this.someValue = pSomeValue;
+ }
+....
+// getter/setter
}
-<!-- Definitions for extent org.apache.ojb.broker.AB -->
- <class-descriptor class="org.apache.ojb.broker.AB">
- <extent-class class-ref="org.apache.ojb.broker.A" />
- <extent-class class-ref="org.apache.ojb.broker.B" />
- </class-descriptor>
+public static class B1 extends B
+{
+ public B1()
+ {
+ super();
+ }
-<!-- Definitions for org.apache.ojb.broker.A -->
- <class-descriptor
- class="org.apache.ojb.broker.A"
- table="AB_TABLE"
- >
- <field-descriptor
- name="id"
- column="ID"
- jdbc-type="INTEGER"
- primarykey="true"
- autoincrement="true"
- />
- <field-descriptor
- name="ojbConcreteClass"
- column="CLASS_NAME"
- jdbc-type="VARCHAR"
- />
- <field-descriptor
- name="someValue"
- column="VALUE_"
- jdbc-type="INTEGER"
- />
- </class-descriptor>]]></source>
+ public B1(int pId, int pSomeValue)
+ {
+ super(pId, pSomeValue);
+ }
+}]]></source>
+ <note>
+ The getter/setter for attribute
<code>ojbConcreteClass</code> in class <code>AB</code>
+ is only needed if OJB is forced to use
+ <a
href="site:advanced-technique/persistent-field">getter/setter for field
access</a>.
+ </note>
+ <p>
+ Here is the metadata mapping for the abstract base class
<code>AB</code>
+ and class <code>B</code>:
+ </p>
+ <source><![CDATA[
+<class-descriptor class="org.apache.ojb.broker.ObjectRepository$AB">
+ <extent-class class-ref="org.apache.ojb.broker.ObjectRepository$A" />
+ <extent-class class-ref="org.apache.ojb.broker.ObjectRepository$B" />
+</class-descriptor>
+
+<class-descriptor
+ class="org.apache.ojb.broker.ObjectRepository$B"
+ table="AB_TABLE"
+>
+ <extent-class class-ref="org.apache.ojb.broker.ObjectRepository$B1" />
+
+ <field-descriptor
+ name="id"
+ column="ID"
+ jdbc-type="INTEGER"
+ primarykey="true"
+ autoincrement="true"
+ />
+ <field-descriptor
+ name="ojbConcreteClass"
+ column="CLASS_NAME"
+ jdbc-type="VARCHAR"
+ />
+ <field-descriptor
+ name="someValue"
+ column="VALUE_"
+ jdbc-type="INTEGER"
+ />
+ <field-descriptor
+ name="someBField"
+ column="B_FIELD"
+ jdbc-type="VARCHAR"
+ />
+</class-descriptor>
+
+<class-descriptor
+ class="org.apache.ojb.broker.ObjectRepository$B1"
+ table="AB_TABLE"
+>
+ <field-descriptor
+ name="id"
+ column="ID"
+ jdbc-type="INTEGER"
+ primarykey="true"
+ autoincrement="true"
+ />
+ <field-descriptor
+ name="ojbConcreteClass"
+ column="CLASS_NAME"
+ jdbc-type="VARCHAR"
+ />
+ <field-descriptor
+ name="someValue"
+ column="VALUE_"
+ jdbc-type="INTEGER"
+ />
+ <field-descriptor
+ name="someBField"
+ column="B_FIELD"
+ jdbc-type="VARCHAR"
+ />
+</class-descriptor>]]></source>
<p>
- The column CLASS_NAME is used to store the concrete type
of each
+ The column <code>CLASS_NAME</code> is used to store the
concrete type of each
object.
</p>
+
+ <anchor id="own-discriminator"/>
+ <section>
+ <title>Implement your own Discriminator Handling</title>
<p>
If you cannot provide such an additional column, but
need to
use some other means of indicating the type of each
object you will require
@@ -397,9 +479,10 @@
</p>
<p>
You have to derive a Class from
-
<code>org.apache.ojb.broker.accesslayer.RowReaderDefaultImpl</code> and
overridee the method
-
<code>RowReaderDefaultImpl.selectClassDescriptor()</code> to implement your
specific type selection
- mechanism. The code of the default implementation looks
like follows:
+
<code>org.apache.ojb.broker.accesslayer.RowReaderDefaultImpl</code> and override
+ the method
<code>RowReaderDefaultImpl.selectClassDescriptor()</code> to implement
+ your specific type selection mechanism. The code of the
default implementation
+ looks like follows:
</p>
<source><![CDATA[
protected ClassDescriptor selectClassDescriptor(Map row)
@@ -407,44 +490,26 @@
{
// check if there is an attribute which tells us
// which concrete class is to be instantiated
- FieldDescriptor concreteClassFD =
- m_cld.getFieldDescriptorByName(
- ClassDescriptor.OJB_CONCRETE_CLASS);
-
- if (concreteClassFD == null)
- return m_cld;
- else
- {
- try
- {
- String concreteClass = (String) row.get(
- concreteClassFD.getColumnName());
- if (concreteClass == null ||
- concreteClass.trim().length() == 0)
- {
- throw new PersistenceBrokerException(
- "ojbConcreteClass field returned null or 0-length
string");
- }
- else
- {
- concreteClass = concreteClass.trim();
- }
- ClassDescriptor result = m_cld.getRepository().
- getDescriptorFor(concreteClass);
- if (result == null)
- {
- result = m_cld;
- }
- return result;
- }
- catch (PBFactoryException e)
+ ClassDescriptor result = m_cld;
+ Class ojbConcreteClass = (Class) row.get(OJB_CONCRETE_CLASS_KEY);
+ if(ojbConcreteClass != null)
+ {
+ result = m_cld.getRepository().getDescriptorFor(ojbConcreteClass);
+ // if we can't find class-descriptor for concrete
+ // class, something wrong with mapping
+ if (result == null)
{
- throw new PersistenceBrokerException(e);
+ throw new PersistenceBrokerException(
+ "Can't find class-descriptor for ojbConcreteClass '"
+ + ojbConcreteClass + "', the main class was "
+ + m_cld.getClassNameOfObject());
}
}
+ return result;
}]]></source>
<p>
- After implementing this class you must edit the
ClassDescriptor for
+ After implementing your own <a
href="#using-rowreader"><code>RowReader</code></a>
+ you must edit the ClassDescriptor for
the respective class in the XML repository to specify
the usage of
your RowReader Implementation:
</p>
@@ -458,9 +523,9 @@
>
...]]></source>
<p>
- You will learn more about RowReaders in the
- <a href="#using-rowreader">next section.</a>
+ You will learn more about RowReaders in <a
href="#using-rowreader">this section.</a>
</p>
+ </section>
</section>
<anchor id="table-per-subclass"/>
No revision
No revision
1.3.2.22 +2 -1
db-ojb/src/doc/forrest/src/documentation/content/xdocs/site.xml
Index: site.xml
===================================================================
RCS file:
/home/cvs/db-ojb/src/doc/forrest/src/documentation/content/xdocs/site.xml,v
retrieving revision 1.3.2.21
retrieving revision 1.3.2.22
diff -u -r1.3.2.21 -r1.3.2.22
--- site.xml 16 Dec 2005 20:55:48 -0000 1.3.2.21
+++ site.xml 17 Dec 2005 01:39:41 -0000 1.3.2.22
@@ -256,6 +256,7 @@
<pb-lifecycle-listener
href="org/apache/ojb/broker/PBLifeCycleListener.html"/>
<pb-state-listener
href="org/apache/ojb/broker/PBStateListener.html"/>
<pb-aware
href="org/apache/ojb/broker/PersistenceBrokerAware.html"/>
+ <query-factory
href="org/apache/ojb/broker/query/QueryFactory.html"/>
<!-- odmg-api classes -->
<odmg-transaction href="org/odmg/Transaction.html"/>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]