OJB
Downloads
Documentation
Development
Translated (Web)
|
Acquiring and building |
The XDoclet OJB module is part of OJB source. As such, the source of the module is part of the OJB source
tree and can be found in directory src/xdoclet. Likewise, binary versions of the module and the required
libraries (xjavadoc, xdoclet) are to be found in the lib folder.
In order to build the XDoclet OJB module from source, you'll need a source distribution of XDoclet
version 1.2, either a source distribution from the sourceforge download site or a CVS checkout/drop. See
the XDoclet website at
http://xdoclet.sourceforge.net/install.html for
details.
|
Usage |
Using the XDoclet OJB module is rather easy. Put the module jar along with the xdoclet jar in a place
where ant will find it, and then invoke it in your build file like:
 |  |  |
 |
<target name="repository-files">
<taskdef name="ojbdoclet"
classname="xdoclet.modules.ojb.OjbDocletTask"
classpathref="build-classpath">
<ojbdoclet destdir="./build">
<fileset dir="./src"/>
<ojbrepository destinationFile="repository_user.xml"/>
<torqueschema databaseName="test" destinationFile="project_schema.xml"/>
</ojbdoclet>
</target>
|  |
 |  |  |
The XDoclet OJB module has two sub tasks, ojbrepository and torqueschema ,
which generate the OJB repository part containing the user descriptors and the torque table schema,
respectively. Please note that the XDoclet OJB module (like all xdoclet tasks) expects the directory
structure of its input java source files to match their package structure. In this regard it is
similar to the javac ant task.
The main ojbdoclet task has two attributes:
-
destdir
- The destination directory where generated files will be placed.
-
checks : none | basic | strict (default)
- The amount of the checks performed. Per default,
strict checks are performed which
means that for instance classes specified in an attribute (e.g. collection-class ,
row-reader etc.) are loaded from the classpath and checked. So in this mode
it is necessary to have OJB as well as the processed classes on the classpath (using the
classpathref attribute of the taskdef ant task above). If this is
for some reason not possible, then use basic which performs most of the
checks but does not load classes from the classpath. none does not perform any
checks so use it with care and only if really necessary (in this case it would be helpful
if you would post the problem to the ojb-user mailing list).
The ojbrepository subtask has the following attributes:
-
destinationFile
- Specifies the output file. The default is
repository_user.xml .
-
verbose : true | false (default)
- Whether the task should output some information about its progress.
The torqueschema subtask has these attributes:
-
databaseName
- This attribute gives the name of the database for torque (required).
-
destinationFile
- The output file, default is
project_schema.xml .
-
dtdUrl
- Allows to specify the url of the torque dtd. This is necessary e.g. for XML parsers that have
problems with the default dtd url (http://jakarta.apache.org/turbine/dtd/database.dtd), or
when using a newer version of torque.
-
generateForeignkeys : true (default) | false
- Whether foreignkey tags are generated in the torque database schema.
-
verbose : true | false (default)
- Whether the task outputs some progress information.
The classpathref attribute in the taskdef can be used to define the classpath for xdoclet
(containing the xdoclet and ojb module jars), e.g. via:
 |  |  |
 |
<path id="build-classpath">
<fileset dir="lib/xdoclet">
<include name="**/*.jar"/>
</fileset>
</path>
|  |
 |  |  |
Using the generated torque schema is a bit more tricky. The easiest way is to use the
build-torque.xml script which is part of OJB. Include the lib subdirectory of the OJB
distribution which also includes torque (e.g. in build-classpath as shown above). You
will also want to use your OJB settings (build.properties, profile/${database}.profile), so include
them at the beginning of the build script:
 |  |  |
 |
<property file="build.properties"/>
<property file="mysql.profile"/>
|  |
 |  |  |
Now you can create the database with the following ant calls:
 |  |  |
 |
<target name="init-db" depends="repository-files">
<ant dir="."
antfile="build-torque.xml"
target="project-sql-classpath">
<property name="schemaDirectory" value="."/>
<property name="outputDirectory" value="build/db"/>
</ant>
<ant dir="."
antfile="build-torque.xml"
target="project-create-db-classpath">
<property name="schemaDirectory" value="."/>
<property name="outputDirectory" value="build/db"/>
</ant>
<ant dir="."
antfile="build-torque.xml"
target="project-insert-sql">
<property name="schemaDirectory" value="."/>
<property name="outputDirectory" value="build/db"/>
</ant>
</target>
|  |
 |  |  |
As you can see, it is possible (and sometimes advisable) to override properties for the called tasks.
In the example above, the property schemaDirectory points to the directory containing the
*-schema.xml files, and outputDirectory to the directory where torque will
generate the SQL scripts and puts the log. If you need to manipulate the directory where the Torque
build script searches for the libraries, then set the lib.dir property to a directory
containing the libraries. Due to limitations in the Torque build script, all libraries needed by it
have to be in a single directory.
One important thing to note here is that the latter two calls modify the database and in the process
remove any existing data, so use them with care. Similar to the above targets, you can use the
additional targets project-datadump-classpath for storing the database data in an XML
file, and project-datasql-classpath to inserting data from an XML file into the
database.
Also, these steps are only valid for the torque that is delivered with OJB, but probably not for newer
or older versions.
|
Interfaces and Classes |
ojb.class |
The ojb.class tag marks interfaces and classes that shall be present in the repository
descriptor. This includes types that are used as reference targets or as collection elements, but
for instance not abstract base classes not used elsewhere.
Attributes:
-
attributes
- Optionally contains attributes of the class as a comma-separated list of name-value
pairs.
-
determine-extents : true (default) | false
- When set to
true , then the XDoclet OJB module will automatically determine all
extents (ojb-relevant sub types) of this type. If set to false , then extents need to
be specified via the ojb.extent-class class tag (see below).
-
documentation
- Optionally contains documentation on the class.
-
generate-table-info : true (default) | false
- This attribute controls whether the type has data and should therefore get a torque table
descriptor. When set to
false , no field, reference or collection descriptors are
generated.
-
include-inherited : true (default) | false
- Determines whether base type fields/references/collections with the appropriate tags
(ojb.field, ojb.reference,
ojb.collection) will be included in the descriptor and table
definition of this class. Note that all base type fields/references/collections with an
appropriate tag are included regardless of whether the base types have the ojb.class tag or
not.
-
table
- The name of the table used for this type. Is only used when table info is generated. If not
specified, then the short name of the type is used.
The following class-descriptor attributes are also supported in the ojb.class
tag and will be written directly to the generated class descriptor (see the
repository.dtd for their meaning):
-
accept-locks
-
factory-class
-
factory-method
-
initialization-method
-
isolation-level
-
proxy
-
proxy-prefetching-limit
-
refresh
-
row-reader
Example: (from the unit tests)
 |  |  |
 |
/**
* @ojb.class generate-table-info="false"
*/
public abstract class AbstractArticle implements InterfaceArticle, java.io.Serializable
...
/**
* @ojb.class table="Artikel"
* proxy="dynamic"
* include-inherited="true"
* documentation="This is important documentation on the Article class."
* attributes="color=blue,size=big"
*/
public class Article extends AbstractArticle implements InterfaceArticle, java.io.Serializable
...
|  |
 |  |  |
The AbstractArticle class will have an class descriptor in the repository file, but
no field, reference or collection descriptors. The Article class however will not
only have descriptors for its own fields/references/collections but also for those inherited from
AbstractArticle . Also, its table definition in the torque file will be called
"Artikel", not "Article". The resulting class descriptors look like:
 |  |  |
 |
<class-descriptor
class="org.apache.ojb.broker.AbstractArticle"
>
<extent-class class-ref="org.apache.ojb.broker.Article"/>
</class-descriptor>
<class-descriptor
class="org.apache.ojb.broker.Article"
proxy="dynamic"
table="Artikel"
>
<documentation>This is important documentation on the Article class.</documentation>
...
<attribute attribute-name="color" attribute-value="blue"/>
<attribute attribute-name="size" attribute-value="big"/>
</class-descriptor>
...
|  |
 |  |  |
|
ojb.insert-procedure |
Identifies the database procedure that shall be used for inserting objects into the database.
Attributes:
-
arguments
- Comma-separated list of names of constant or
runtime arguments that are specified in the same class.
-
attributes
- Contains optional attributes of the procedure in a comma-separated list of name-value pairs.
-
documentation
- Contains optional documentation on the procedure.
-
include-all-fields : true | false (default)
- Specifies whether all persistent fields of the class shall be passed to the procedure. If so, then the
arguments value is ignored.
-
name
- The name of the procedure (required).
-
return-field-ref
- The persistent field that receives the return value of the procedure (should only be used if the
procedure returns a value)
For an example see
constant argument.
|
ojb.update-procedure |
The database procedure that will be used for updating persistent objects in the database.
Attributes:
-
arguments
- A comma-separated list of names of constant or
runtime arguments in the same class.
-
attributes
- The optional attributes of the procedure in a comma-separated list of name-value pairs.
-
documentation
- Optional documentation on the procedure.
-
include-all-fields : true | false (default)
- Whether all persistent fields of the class shall be passed to the procedure in which case the
arguments value is ignored.
-
name
- Name of the database procedure (required).
-
return-field-ref
- A persistent field that will receive the return value of the procedure (only to be used if the
procedure returns a value)
For an example see
runtime argument.
|
|
Fields and Bean properties |
ojb.field |
Fields or accessor methods (i.e. get/is and set methods) for properties are marked with the
ojb.field tag to denote a persistent field. When a method is marked, then the corresponding
bean property is used for naming purposes (e.g. "value" for a method getValue() ). The
XDoclet OJB module ensures that a field is not present more than once, therefore it is safe to mark
both fields and their accessors. However, in that case the three ojb.field tags are required to
have the same attributes.
Marked fields are used for descriptor generation in the same type (if it has an
ojb.class tag) and all sub types with the ojb.class
tag having the include-inherited attribute set to true .
It is also possible to use the ojb.field tag at the class level (i.e. in the JavaDoc comment of
the class). In this case, the tag is used to define an anonymous field, e.g. a "field" that has
no counterpart in the class but exists in the database. For anonymous fields, both the name and
the jdbc-type attributes are required, and the access attribute is ignored (it defaults
to the value anonymous ). Beside these differences, anonymous fields are handled like
other fields, (e.g. they result in field-descriptor entries in the repository descriptor, and in
columns in the table schema, and they are inherited and can be modified via the
ojb.modify-inherited tag.
The XDoclet OJB module orders the fields in the repository
descriptor and table schema according to the following rules:
- Fields (anonymous and non-anonymous) from base types/nested objects and from the current file that
have an id, sorted by the id value. If fields have the same id, then they are sorted following the
rules for fields without an id.
- Fields (anonymous and non-anonymous) from base types/nested objects and from the current file that
have no id, in the order they appear starting with the farthest base type. Per class, the anonymous
fields come first, followed by the non-anonymous fields.
Attributes:
-
access : readonly | readwrite (default)
- Specifies the accessibility of the field.
readonly marks fields that are not to
modified. readwrite marks fields that may be read and written to. Anonymous fields do
not have to be marked (i.e. anonymous value) as the position of the ojb.field
tag in the class JavaDoc comment suffices.
-
attributes
- Optionally contains attributes of the field as a comma-separated list of name-value pairs.
-
autoincrement : none (default) | ojb | database
- Defines whether this field gets its value automatically. If
ojb is specified, then
OJB fills the value using a sequence manager. If the value is database , then the field
is defined as an autoIncrement field in the torque schema (i.e. the database fills the
field), and OJB has nothing to do with the value of the field. The default value is none
which means that the field is not automatically filled.
-
column
- The name of the database column for this field. If not given, then the name of the attribute is
used.
-
conversion
- The name of the class to be used for conversion between the java type of the field (e.g.
java.lang.Boolean or java.util.Date ) and the java type for the JDBC type
(e.g. java.lang.Integer or java.sql.Date ). Conversion classes must
implement the org.apache.ojb.broker.accesslayer.conversions.FieldConversion
interface. If no explicit JDBC type is defined and the java type has no defined conversion (see
below), then per default the
org.apache.ojb.broker.accesslayer.conversions.Object2ByteArrFieldConversion
conversion class is used.
Default conversion is also used for the following java types when no jdbc type is given (default
type is used instead), and no conversion is specified:
Java type |
Default conversion |
org.apache.ojb.broker.util.GUID |
org.apache.ojb.broker.accesslayer.conversions.GUID2StringFieldConversion |
-
documentation
- Optionally contains documentation on the field.
-
id
- An integer specifying the position in the repository descriptor and table schema. For the
placement rules see above.
-
jdbc-type : BIT | TINYINT | SMALLINT | INTEGER | BIGINT | DOUBLE | FLOAT | REAL | NUMERIC
| DECIMAL | CHAR | VARCHAR | LONGVARCHAR | DATE | TIME | TIMESTAMP | BINARY | VARBINARY
| LONGVARBINARY | CLOB | BLOB | STRUCT | ARRAY | REF | BOOLEAN | DATALINK
- The JDBC type for the column. The XDoclet OJB module will automatically determine a jdbc type for
the field if none is specified. This means that for anonymous fields, the jdbc-type
attribute is required. The automatic mapping performed by the XDoclet OJB module from java type to
jdbc type is as follows:
Java type |
JDBC type |
boolean |
BIT |
byte |
TINYINT |
short |
SMALLINT |
int |
INTEGER |
long |
BIGINT |
char |
CHAR |
float |
REAL |
double |
FLOAT |
java.lang.Boolean |
BIT |
java.lang.Byte |
TINYINT |
java.lang.Short |
SMALLINT |
java.lang.Integer |
INTEGER |
java.lang.Long |
BIGINT |
java.lang.Character |
CHAR |
java.lang.Float |
REAL |
java.lang.Double |
FLOAT |
java.lang.String |
VARCHAR |
java.util.Date |
DATE |
java.sql.Date |
DATE |
java.sql.Time |
TIME |
java.sql.Timestamp |
TIMESTAMP |
java.sql.Blob |
BLOB |
java.sql.Clob |
CLOB |
java.sql.Ref |
REF |
java.sql.Struct |
STRUCT |
java.math.BigDecimal |
DECIMAL |
org.apache.ojb.broker.util.GUID |
VARCHAR |
For any other type (including array types) the default mapping is to LONGVARBINARY
using the Object2ByteArrFieldConversion conversion (see conversion attribute
above).
-
length
- The length of the column if required by the jdbc type. Note that due to restrictions in some
database (e.g. MySQL), for some types, the XDoclet OJB module imposes default lengths if no length
is specified:
Jdbc type |
Default length |
CHAR |
1 |
VARCHAR |
24 |
LONGVARCHAR |
24 |
-
name
- The name of the field. This attribute is required for anonymous fields, otherwise it is
ignored.
-
precision
scale
- The precision and scale of the column if required by the jdbc type. They are usually used in
combination with the
DECIMAL and NUMERIC types, and then specifiy the
number of digits before (precision) and after (scale) the comma (excluding the
plus/minus sign). Due to restrictions in some database (e.g. MySQL), the XDoclet OJB module
imposes default values for some types if none are specified:
Jdbc type |
Default values for precision, scale |
DECIMAL |
20,0 (this corresponds to the range of long where the longest number
is -9223372036854775808). |
NUMERIC |
20,0 |
For other types, if only the precision is specified, the scale defaults to 0. If only scale is
specified, precision defaults to 1.
Other attributes supported in the ojb.field tag that have the same meaning as in the
repository descriptor (and partly in the torque
table schema) are:
-
default-fetch
-
indexed
-
locking
-
nullable
-
primarykey
-
sequence-name
-
update-lock
Examples:
 |  |  |
 |
/**
* @ojb.field column="Auslaufartikel"
* jdbc-type="INTEGER"
* conversion="org.apache.ojb.broker.accesslayer.conversions.Boolean2IntFieldConversion"
* id="10"
* attributes="color=green,size=small"
*/
protected boolean isSelloutArticle;
|  |
 |  |  |
will result in the following field descriptor:
 |  |  |
 |
<field-descriptor
name="isSelloutArticle"
column="Auslaufartikel"
jdbc-type="INTEGER"
conversion="org.apache.ojb.broker.accesslayer.conversions.Boolean2IntFieldConversion"
>
<attribute attribute-name="color" attribute-value="green"/>
<attribute attribute-name="size" attribute-value="small"/>
</field-descriptor>
|  |
 |  |  |
The column descriptor looks like:
 |  |  |
 |
<table name="Artikel">
...
<column name="Auslaufartikel"
javaName="isSelloutArticle"
type="INTEGER"
/>
...
</table>
|  |
 |  |  |
An anonymous field is declared like this:
 |  |  |
 |
/**
* @ojb.class table="TABLE_F"
* include-inherited="false"
* @ojb.field name="eID"
* column="E_ID"
* jdbc-type="INTEGER"
* @ojb.reference class-ref="org.apache.ojb.broker.E"
* auto-retrieve="true"
* auto-update="true"
* auto-delete="true"
* foreignkey="eID"
*/
public class F extends E implements Serializable
...
|  |
 |  |  |
In this case an anonymous field is declared and also used as the foreignkey of an anonymous reference.
The corresponding class descriptor looks like:
 |  |  |
 |
<class-descriptor
class="org.apache.ojb.broker.F"
table="TABLE_F"
>
<field-descriptor
name="eID"
column="E_ID"
jdbc-type="INTEGER"
access="anonymous"
>
</field-descriptor>
...
<reference-descriptor
name="super"
class-ref="org.apache.ojb.broker.E"
auto-retrieve="true"
auto-update="true"
auto-delete="true"
>
<foreignkey field-ref="eID"/>
</reference-descriptor>
</class-descriptor>
|  |
 |  |  |
Here the anonymous field and reference (which implicitly refers to super ) are used to
establish the super-subtype relationship between E and F on the database
level. For details on this see the
tutorial.
|
|
References |
ojb.reference |
Similar to fields, references (java fields or accessor methods) are marked with the
ojb.reference tag. We have a reference when the type of the java field is itself a persistent
class (has an ojb.class tag) and therefore the java field represents an
association. This means that the referenced type of an association (or the one specified by the
class-ref attribute, see below) is required to be present in the repository descriptor (it has
the ojb.class tag).
Foreign keys of references are also declared in the torque table schema (see example below).
OJB currently requires that the referenced type has at least one field used to implement the
reference, usually some id of an integer type.
A reference can be stated in the JavaDoc comment of the class (anonymous reference), but in this case
it silently refer to super (see the example of ojb.field)
which can be used to establish an inheritance relationship. Note that anonymous references are not
inherited (in contrast to anonymous fields and normal references).
Attributes:
-
attributes
- Optionally contains attributes of the reference as a comma-separated list of name-value
pairs.
-
class-ref
- Allows to explicitly specify the referenced type. Normally the XDoclet OJB module searches the
type of the field and its sub types for the nearest type with the
ojb.class tag. If the type is specified explicitly, then this type is
used instead. For anonymous references, the class-ref has to specified as there is no field
to determine the type from.
Note that the type is required to have the ojb.class tag.
-
documentation
- Optionally contains documentation on the reference.
-
foreignkey
- Contains one or more foreign key fields separated by commas (required). The foreign key fields are fields
with the ojb.field tag in the same class as the reference, which
implement the association, i.e. contains the values of the primarykeys of the referenced object.
Other supported attributes (see repository.dtd for their
meaning) written directly to the repository descriptor file:
-
auto-delete
-
auto-retrieve
-
auto-update
-
otm-dependent
-
proxy
-
proxy-prefetching-limit
-
refresh
Example:
 |  |  |
 |
public abstract class AbstractArticle implements InterfaceArticle, java.io.Serializable
{
protected InterfaceProductGroup productGroup;
/**
* @ojb.reference class-ref="org.apache.ojb.broker.ProductGroup"
* foreignkey="productGroupId"
* documentation="this is the reference to an articles productgroup"
* attributes="color=red,size=tiny"
*/
protected InterfaceProductGroup productGroup;
/**
* @ojb.field
*/
protected int productGroupId;
...
}
|  |
 |  |  |
Here the java type is InterfaceProductGroup although the repository reference uses the
sub type ProductGroup . The generated reference descriptor looks like:
 |  |  |
 |
<field-descriptor
name="productGroupId"
column="Kategorie_Nr"
jdbc-type="INTEGER"
>
</field-descriptor>
<reference-descriptor
name="productGroup"
class-ref="org.apache.ojb.broker.ProductGroup"
>
<documentation>this is the reference to an articles productgroup</documentation>
<attribute attribute-name="color" attribute-value="red"/>
<attribute attribute-name="size" attribute-value="tiny"/>
<foreignkey field-ref="productGroupId"/>
</reference-descriptor>
|  |
 |  |  |
In the torque table schema for the Article class, the foreign key for the product group
is explicitly declared:
 |  |  |
 |
<table name="Artikel">
...
<column name="Kategorie_Nr"
javaName="productGroupId"
type="INTEGER"
/>
...
<foreign-key foreignTable="Kategorien">
<reference local="Kategorie_Nr" foreign="Kategorie_Nr"/>
</foreign-key>
</table>
|  |
 |  |  |
For an example of an anonymous reference, see the examples of
ojb.field.
|
|
Collections |
ojb.collection |
Persistent collections which implement 1:n or m:n associations are denoted by the
ojb.collection tag. If the collection is an array, then the XDoclet OJB module can determine
the element type automatically (analogous to references). Otherwise the type must be specified using
the element-class-ref attribute. m:n associations are also supported (collections on both
sides) via the indirection-table, foreignkey and remote-foreignkey attributes.
Attributes:
-
attributes
- Optionally contains attributes of the collection as a comma-separated list of name-value
pairs.
-
collection-class
- Specifies the class that implements the collection. This attribute is usually only required if
the actual type of the collection object shall be different from the variable type.
Collection classes that implement java.util.Collection can be handled by OJB as-is
so specifying them is not necessary. For the types that do not, the XDoclet OJB module checks
whether the collection field type implements the
org.apache.ojb.broker.ManageableCollection interface, and if so, generates the
collection-class attribute automatically.
-
documentation
- Optionally contains documentation on the collection.
-
element-class-ref
- Allows to explicitly specify the type of the collection elements. Note that the type is required
to have the ojb.class tag.
-
foreignkey
- Contains one or more foreign key field or columns separated by commas (required).
If the collection implements an 1:n association, then this attribute specifies the fields in the
element type that implement the association on the element side, i.e. they refer to the primary
keys of the class containing this collection. Note that these fields are required to have the
ojb.field tag.
When the collection is one part of an m:n association (e.g. with an indirection table), this
attribute specifies the columns in the indirection table that point to the type owning this
collection. This attribute is required of both collections. If the other type has no explicit
collection, use the remote-foreignkey attribute to specify the foreign keys for the other
type.
-
indirection-table
- Gives the name of the indirection table used for m:n associations. The XDoclet OJB module will
create an appropriate torque table schema. The specified foreign keys are taken from the
foreignkey attribute in this class and the corresponding collection in the element class,
or if the element class has no collection, from the remote-foreignkey attribute of this
collection. The XDoclet OJB module associates the foreignkeys (in the order they are stated in the
foreignkey/remote-foreignkey attributes) to the ordered primarykey fields (for the
ordering rules see the ojb.field tag), and use ther jdbc
type (and length setting if necessary) of these primarey keys for the columns.
-
orderby
- Contains the fields used for sorting the collection and, optionally, the sorting order (either
ASC or DESC for ascending or descending, respectively) as a
comma-separated list of name-value pairs. For instance, field1=DESC,field2,field3=ASC
specifies three fields after which to sort, the first one in descending order and the other two in
ascending order (which is the default and can be omitted).
-
query-customizer
- Specifies a query customizer for the collection. The type is required to implement
org.apache.ojb.broker.accesslayer.QueryCustomizer .
-
query-customizer-attributes
- Specifies attributes for the query customizer. This attribute is ignored if no query customizer
is specified for this collection.
-
remote-foreignkey
- Contains one or more foreign key columns (separated by commas) in the indirection table pointing
to the elements. Note that this field should only be used if the other type does not have a
collection itself which the XDoclet OJB module can use to retrieve the foreign keys. This
attribute is ignored if used with 1:n collections (no indirection table specified).
The same attributes as for references are written directly to the repository descriptor file (see
repository.dtd) :
-
auto-delete
-
auto-retrieve
-
auto-update
-
otm-dependent
-
proxy
-
proxy-prefetching-limit
-
refresh
Examples:
 |  |  |
 |
/**
* @ojb.collection element-class-ref="org.apache.ojb.broker.Article"
* foreignkey="productGroupId"
* auto-retrieve="true"
* auto-update="false"
* auto-delete="true"
* orderby="productGroupId=DESC"
* query-customizer="org.apache.ojb.broker.accesslayer.QueryCustomizerDefaultImpl"
* query-customizer-attributes="attr1=value1"
*/
private ArticleCollection allArticlesInGroup;
|  |
 |  |  |
The corresponding collection descriptor is:
 |  |  |
 |
<collection-descriptor
name="allArticlesInGroup"
element-class-ref="org.apache.ojb.broker.Article"
collection-class="org.apache.ojb.broker.ArticleCollection"
auto-retrieve="true"
auto-update="false"
auto-delete="true"
>
<orderby name="productGroupId" sort="DESC"/>
<inverse-foreignkey field-ref="productGroupId"/>
<query-customizer class="org.apache.ojb.broker.accesslayer.QueryCustomizerDefaultImpl">
<attribute attribute-name="attr1" attribute-value="value1"/>
</query-customizer>
</collection-descriptor>
|  |
 |  |  |
An m:n collection is defined using the indirection-table attribute:
 |  |  |
 |
/**
* @ojb.class generate-table-info="false"
*/
public abstract class BaseContentImpl implements Content
{
/**
* @ojb.collection element-class-ref="org.apache.ojb.broker.Qualifier"
* auto-retrieve="true"
* auto-update="false"
* auto-delete="false"
* indirection-table="CONTENT_QUALIFIER"
* foreignkey="CONTENT_ID"
* remote-foreignkey="QUALIFIER_ID"
*/
private List qualifiers;
...
}
/**
* @ojb.class table="NEWS"
*/
public class News extends BaseContentImpl
{
...
}
/**
* @ojb.class generate-table-info="false"
*/
public interface Qualifier extends Serializable
{
...
}
|  |
 |  |  |
The BaseContentImpl has a m:n association to the Qualifier interface. for
the BaseContentImpl class, this association is implemented via the
CONTENT_ID column (specified by the foreignkey) in the indirection table
CONTENT_QUALIFIER . Usually, both ends of an m:n association have a collection
implementing the association, and for both ends the foreignkey specifies the indirection table
column pointing to the class at this end. The Qualifier interface however does not
contain a collection which could be used to determine the indirection table column that implements the
association from its side. So, this column is also specified in the BaseContentImpl class
using the remote-foreignkey attribute. The class descriptors are:
 |  |  |
 |
<class-descriptor
class="org.apache.ojb.broker.BaseContentImpl"
>
<extent-class class-ref="org.apache.ojb.broker.News"/>
</class-descriptor>
<class-descriptor
class="org.apache.ojb.broker.News"
table="NEWS"
>
...
<collection-descriptor
name="qualifiers"
element-class-ref="org.apache.ojb.broker.Qualifier"
indirection-table="CONTENT_QUALIFIER"
auto-retrieve="true"
auto-update="false"
auto-delete="false"
>
<fk-pointing-to-this-class column="CONTENT_ID"/>
<fk-pointing-to-element-class column="QUALIFIER_ID"/>
</collection-descriptor>
</class-descriptor>
<class-descriptor
class="org.apache.ojb.broker.Qualifier"
>
<extent-class class-ref="org.apache.ojb.broker.BaseQualifierImpl"/>
</class-descriptor>
|  |
 |  |  |
As can be seen, the collection definition is inherited in the News class and the two
indirection table columns pointing to the ends of the m:n associaton are correctly specified.
|
|
Nested objects |
ojb.nested |
The features of a class can be included in another class by declaring a field of that type and using
this tag. The XDoclet OJB module will then add every tagged feature (i.e. fields/bean properties
with ojb.field, ojb.reference or
ojb.collection tag, or even with ojb.nested) from the type
of the field to the current class descriptor. It is not required that the field's type has the
ojb.class tag, though.
All attributes of the features are copied (even primarykey) and modified if necessary
(e.g. the foreignkey of a reference is adjusted accordingly). For changing an attribute
use the ojb.modify-nested tag.
For an example of nesting, see the example of ojb.modify-nested.
|
|
|