The JDO Metadata


The JDO metadata is contained in one or more XML files. The metadata identifies and describes the application data classes. Both the enhancer and the JDO runtime use the metadata. Behavior is unspecified if the metadata files are changed between enhancement and runtime.

The Names and Locations of the JDO Metadata Files

JDO requires that the file containing metadata for an application data class is available where the class loader that loaded the application data class can find it. Each class loader searches a set of class paths for class files and resource files. For more information, refer to the SDK's Javadoc for the getResource method in the java.lang.ClassLoader class.

JDO 1.0 recommended, but did not require, that the file name be either <class-name>.jdo or <package-name>.jdo. Because the 1.0 specification did not require conformity, the locations and names of the metadata files were often not portable across implementations. JDO 1.0.1 is much more specific about the names and locations of metadata files. The requirements for names and locations apply for both the enhancer and the JDO runtime.

In JDO 1.0.1, the allowed names must be either <class-name>.jdo or package.jdo. For example, if the application data class is com.ysoft.jdo.Heffalump, then using the class-name option, the metadata file name must be Heffalump.jdo. Using the package name option, the metadata file name must be package.jdo.

A metadata file named with the class name option can describe only its class. The metadata files named package.jdo can describe one or more classes in one or more packages.

In the case of the class name option, the metadata file has only one location, the directory of the package where the application data class resides. For example, the location for the Heffalump.jdo file can only be the com/ysoft/jdo directory. In the case of the package name option, there are several possible locations.

JDO defines the search order for metadata files. JDO searches at each segment of the package name for a file named package.jdo. The last file that it searches for is the <class-name>.jdo file located in the package with the class file. For example, to find the metadata for the com.ysoft.jdo.Heffalump class, JDO uses the following search order:

  1. META-INF/package.jdo

  2. WEB-INF/package.jdo

  3. package.jdo

  4. com/package.jdo

  5. com/ysoft/package.jdo

  6. com/ysoft/jdo/package.jdo

  7. com/ysoft/jdo/Heffalump.jdo

JDO may find a file at each step in the search. In this case, JDO searches in each metadata file that it finds for the metadata that describes the Heffalump class. The search stops once the metadata for the desired class is found. As a result, it is possible for the metadata in one of the earlier locations to override the metadata in one of the later locations.

The metadata for one class may be loaded as the result of a search for the metadata for another class. For example, the metadata for the org.abc.Woozle class may be loaded from the WEB-INF/package.jdo that was found while searching for the metadata for the com.ysoft.jdo.Heffalump class. This behavior is pernicious only when the metadata for a class is stored in an unnatural location. Although you can put the metadata for the org.abc.Woozle class in the com/ysoft/jdo/package.jdo metadata file, doing so is likely to cause confusion.

To ease upward migration, JDO 1.0.1 allows the JDO implementation to first search for metadata files using the search order and names that it used in its 1.0 implementation before searching in the order and for the names that the 1.0.1 specification requires.

The Structure of the JDO Metadata

The JDO metadata provides information about the application data classes. It determines the identity type used by each application data class. It identifies the managed fields and the unmanaged fields, and it provides other information, some of which is implementation dependent. Every application data class must be identified in the JDO metadata. The metadata does not include application classes that are only persistence aware.

The JDO metadata is an XML file. The document type definition is contained in the jdo.dtd file found in the JDO Jar file. The JDO metadata has eight types of XML elements or tags, which are shown in Figure 5-2. The figure shows the hierarchy of the elements, and it indicates the number of times that a child element (or a choice from a group of child elements) may appear within the parent element. Special characters indicate the cardinality of the nested elements.

click to expand
Figure 5-2: The XML elements of the JDO metadata

  • A question mark (?) indicates that the element or choice may appear zero or one time inside its parent element.

  • A plus sign (+) indicates that the element or choice must appear one or more times inside its parent element.

  • An asterisk (*) indicates that the element or choice may appear zero or more times inside its parent element.

As can be seen from Figure 5-2, the metadata provides information on the packages, classes, and fields to be enhanced. Although a JDO metadata file can be quite complex, it can also be quite simple, as the example in Listing 5-4 shows.

Listing 5-4: Simple JDO Metadata File

start example
 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jdo PUBLIC       "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 1.0//EN"       "http://java.sun.com/dtd/jdo_1_0.dtd"> <jdo>    <package name="com.ysoft.jdo.book.coffee">       <class name="CoffeeUrn" identity-type="datastore" />    </package> </jdo> 
end example

The metadata must identify every application data class, but individual fields within the application data class need only be identified if there is something about them that is different from the default or implied values that the enhancer and runtime assume.

The jdo Tag

The jdo tag has no attributes. It is the root tag of the JDO metadata document.

The package Tag

The package tag has one required attribute name, and no optional attributes. The value of the name attribute must be the full package name. The package tag identifies a package containing application data classes to be enhanced. The following example shows the package tag:

 <package name="com.ysoft.jdo.book.library"> 

There are one or more package tags nested within the jdo tag.

The class Tag

The class tag identifies a specific application data class to enhance. There is one class tag, nested within the package tag, for every application data class within the package. Table 5-1 describes the five attributes of the class tag.

Table 5-1: Attributes of the Metadata class Tag

Attribute

Description

Values

Required

Default

name

Name of the class

Text

Yes

No default

identity-type

Type of JDO identity

"application", "datastore", "nondurable"

No

Implied

requires-extent

Determines if class must have an extent

"true", "false"

No

"true"

objectid-class

Name of application identity class

Text

No

No default

persistence-capable-superclass

The next superclass that is enhanced in the inheritance tree

Text

No

No default

The name Attribute

The class name specified in the name attribute is relative to the package named in the enclosing package tag.

The identity-type Attribute

The identity-type attribute takes one of the three values "application", "datastore", or "nondurable". These values correspond to the three types of JDO identity. The implied value is "application" when an objectid-class attribute is specified and "datastore" when an objectid-class attribute is not specified.

Although the identity-type attribute is optional, using it makes for good documentation.

The requires-extent Attribute

The requires-extent tag is used only if the application prefers that the class not have an extent. If there is no extent for the class, then calling the persistence manager's getExtent method throws a JDOUserException.

The objectid-class Attribute

The objectid-class attribute names the application identity class for the application data class. This attribute is required when the identity-type is set to "application", and it is ignored or considered an error otherwise. The name may be fully qualified, or it may be a class name that is relative to the package name of the application data class. The names of inner classes are introduced with the "$" symbol, using the syntax OuterClassName$InnerClassName. This attribute should be omitted if the identity type is anything other than application identity.

The persistence-capable-superclass Attribute

The optional persistence-capable-superclass attribute is used when the enhanced class derives directly or indirectly from another enhanced class. The field's value may be a fully qualified class name, or since JDO 1.0.1, it may be a class name that is relative to the package name of the application data class. This attribute is omitted when the application data class does not have an enhanced superclass. If a non-enhanced class comes between the enhanced class and its enhanced superclass, the value of the attribute still names the closest superclass that is enhanced.

Examples Using the class Tag

The following example shows a class tag that uses all the optional attributes available with datastore identity:

 <class name="AppClassOne"    identity-type="datastore"    requires-extent="true"    persistence-capable-super > 

In this example, AppClassOne derives either directly or indirectly from SomeOtherAppClass. Both are application data classes. Both must use datastore identity, or the enhancer flags an error condition. The identity-type and requires-extent attributes are not required in this example. In this case, they explicitly specify values that would otherwise be implied.

The following example shows a class tag for a class that uses application identity:

 <class name="AppClassTwo"    identity-type="application"    requires-extent="true"    objectid- > 

The static inner class OID is the application identity class for AppClassTwo. As the absence of the persistence-capable-superclass attribute indicates, AppClassTwo does not extend directly or indirectly any other application data class. Neither the identity-type attribute nor the requires-extent attribute are required in this example since they supply values that would otherwise be implied.

Application Identity and Inheritance

To use application identity for application data classes that are related by inheritance, applications should follow these two rules to guarantee portability across all JDO implementations that support application identity:

  • All key fields should be defined in the least-derived application data class, and a corresponding concrete application identity class should be defined for it.

  • Each separate inheritance hierarchy of application data classes should use a different application identity class.

Limits for Application Identity Classes Whose Data Classes Are Related by Inheritance

Although JDO requires that implementations support the portability rules for application identity, it permits JDO implementations to offer more flexibility. The price of this increased flexibility is both more complexity and less portability across JDO implementations. The extent of this flexibility is limited by the following rules:

  • The metadata can declare key fields for only the least-derived concrete classes and their abstract ancestor data classes. The metadata cannot declare a key field for any data class that derives directly or indirectly from a concrete data class.

  • The metadata must declare an identity class for every data class that declares primary key fields.

  • When the data classes form an inheritance hierarchy, the identity classes associated with them must form an inheritance hierarchy that descends in the same order as the data classes. For example, if application data class B derives from application data class A, then the declared application identity class BOID for class B must derive from the application identity class used by class A.

  • The metadata must declare concrete identity classes for the least-derived concrete data classes.

  • The metadata must declare an application identity class for the least-derived application data class.

  • The metadata can declare either an abstract or concrete identity class for an abstract data class.

  • Any application data class derived directly or indirectly from an application data class whose metadata declares a concrete application identity class must use implicitly the concrete application identity class of its ancestor. In the metadata, its class tag cannot declare an objectid-class attribute and its field tags cannot declare a primary-key attribute. In other words, the use of a concrete identity class freezes the application identity for all derived classes.

  • Although no particular application data class is required to declare primary key fields, there have to be primary key fields declared someplace in the inheritance hierarchy of every concrete application data class.

  • Unless an abstract data class is the least-derived data class or has key fields, the metadata does not need to declare an identity class for it.

  • Classes that are not application data classes that may appear in the inheritance hierarchy are ignored when interpreting these rules.

If JDO's two rules for portable application identity, mentioned in the preceding section, are too strict for your application, then you should consult the vendor's documentation to understand what the vendor's implementation allows. You may or may not get the flexibility that the ten rules presented here allow.

The field Tag

The use of field tags is optional. The enhancer discovers the member fields of the application data class by reflection. There is no need to enumerate them in the metadata. At runtime, the application data class knows its managed fields as a result of the changes made during enhancement.

A field tag is required when the implied or default value for one of its attributes is not the desired value. For many fields, the implied or default values are suitable. For these fields, the field tag can be omitted. When present, the field tags are nested within an enclosing class tag. Table 5-2 describes the six attributes of the field tag.

Table 5-2: Attributes of the Metadata field Tag

Attribute

Description

Values

Required

Default

name

Name of the field

Text

Yes

No default

primary-key

Key field for application identity

"true", "false"

No

"false"

persistence-modifier

Managed or unmanaged

"persistent", "transactional", "none"

No

Implied

null-value

Null value allowed

"exception", "default", "none"

No

"none"

default-fetch-group

Member of default fetch group

"true", "false"

No

Implied

embedded

Value (or object) stored as part of this object

"true", "false"

No

Implied

The name Attribute

The name is the only required attribute of the field tag. Its value is the name of the field as declared in the Java class.

The primary-key Attribute

The primary-key attribute identifies the key fields in the application data class. It takes one of two values, "true" or "false". When the attribute is omitted, the default value is "false". This attribute is used only when the class uses application identity. The primary key field must be persistent.

The persistence-modifier Attribute

The persistence-modifier attribute determines whether a field is managed or unmanaged, and if managed, whether it is managed persistently and transactionally or only transactionally. It takes one of three values. The value "persistent" means that the field is both persistent and transactional. The value "transactional" means that the field is only transactional. The value "none" means that the field is unmanaged.

If the persistence-modifier attribute is omitted, the implied value depends on the field's type and modifiers as declared in the application data class. If the field's declaration includes a static, final, or transient modifier, then the implied and required value is "none". Otherwise, if the field's type is any of the types on the following list, then the implied value is "persistent":

  • Any enhanced application data class

  • The eight primitive types: char, byte, short, int, long, float, double, and boolean, and their immutable wrapper classes in the java.lang package

  • The immutable class java.lang.String

  • The immutable class java.util.Locale

  • Either of the two immutable classes from the java.math package: BigDecimal and BigInteger

  • The mutable class java.util.Date

  • Any of eight collection and map classes in the java.util package: HashSet, Hashtable, Vector, ArrayList, LinkedList, HashMap, TreeMap, TreeSet

  • Any of four interface types in the java.util package: Collection, Set, Map, and List

  • Arrays of any of the preceding types except arrays of collection types and map types

Otherwise, the attribute's implied value is "none". The attribute never takes an implied value of "transactional".

The null-value Attribute

The null-value attribute determines the treatment that JDO gives to persistent fields that have null values when the persistent state is stored in the datastore. It takes one of three values: "exception", "none", or "default". The default value for the attribute is "none".

If the value of the null-value attribute is "exception", then JDO throws a JDOUserException when the field's value is null and JDO must store its value in the datastore.

If the value of the null-value attribute is "none", then JDO stores whatever value, including a null, that is in the field. If the datastore rejects the null value, then JDO throws a JDOUserException.

Some datastores can be configured to apply a default value when they are asked to store either no value or a null value for a field. When the value of the null-value attribute is "default" and the object's field has a null value during the store, then the object's field acquires the default value, if any, that the datastore applies. For efficiency, the "default" setting should be used only when there is a likelihood that the datastore will be configured to supply a default value.

The default-fetch-group Attribute

The default-fetch-group attribute determines whether a field is in the default fetch group or not. JDO defines a default fetch group for performance reasons. For most datastores, the object's fields that have particular types are stored together and can be converted easily to their corresponding Java types. As a result, the values of these fields can be loaded together at a substantial discount to the cost of loading each of them separately. JDO defines the default fetch group, but the implementation decides when to use it.

When a field is not persistent or when it is both persistent and a primary key field, then the implied and required value of its default-fetch-group attribute is "false". If the field is persistent and has one of the following types, then its implied value is "true":

  • The eight primitive types and their immutable wrapper classes

  • The BigDecimal and BigInteger classes

  • The String class

  • The java.util.Date class

Otherwise, the implied value is "false".

The implied value for default-fetch-group attribute is usually the value desired for overall optimal performance.

The embedded Attribute

The embedded tag takes a value of "true" or "false". It specifies whether JDO stores the object assigned to the persistent field as a first class object ("false") or a second class object ("true"). Due to many difficulties, JDO 1.0.1 nearly outlaws changing the implied value of this attribute. Later versions of JDO are likely to introduce further changes to this attribute. As a result, avoid when possible using this tag in the JDO metadata.

When a field is not persistent, the implied and required value of the embedded attribute is "false".

When the persistent field's type is any of the following types, the implied and required value of the embedded tag is "true":

  • The eight primitive types and their immutable wrapper classes

  • The BigDecimal and BigInteger classes

  • The String class

  • The java.util.Date and java.util.Locale classes

  • Arrays of any of the preceding types, or of application data classes, but not of collection or map types

  • All the collection and map types

Embedding an array, collection, or map type does not mean that the elements of the array, collection, or map are embedded. See the collection, map, and array tags in the sections that follow in this chapter.

When the persistent field's type is an application data class, an interface type other than the Collection, List, or Map interfaces, or an Object, the implied value for the embedded attribute is "false". Setting the value of the embedded attribute to "true" in these cases is a hint to the JDO implementation to store the application data object as a second class object. However, the implementation may disregard the hint. When the JDO implementation follows the hint, JDO does not specify uniform behavior across all JDO implementations. Any behavior that a particular JDO implementation provides is implementation dependent. Later versions of JDO will likely clarify how an application can define a second class object and what behavior to expect when it does so.

When the JDO implementation supports a persistent type only because it implements the Serializable interface, fields of that type are embedded, but the implied value of the embedded tag is "false". It must be explicitly set to "true".

Example Using the field Tag

In the following example, a Widget application data class has the following member field:

 private Widget mate; 

The following field tag, using the one required and five optional attributes of this type of tag, describes the persistent field mate:

 <field    name="mate"    primary-key="false"    persistence-modifier="persistent"    null-value="none"    default-fetch-group="false"    embedded="false" /> 

Since only the name attribute is required and none of the optional attributes in this example applies a value different from the attribute's implied value, the field tag for the mate field could be shortened to the following:

 <field name="mate" /> 

Since the metadata can omit any field tag that does not apply some nondefault value for an optional attribute, the metadata for the Widget class may not need a field tag at all for the mate field. In general, field tags are used only to specify attribute values that are contrary to the implied or default values or to enclose other tags, such as extension or collection tags.

The collection, map, and array Tags

The field tag may enclose one of the three tags: collection, map, or array. One of these tags describes the field when it is a reference to any of the collection, map, or array types.

The collection Tag

Although the collection tag is optional, it is usually not omitted for a collection field. The JDO implementation can usually do a better job of managing the collection field if it knows the specific type of the collection's elements. Table 5-3 describes the two optional attributes of the collection tag.

Table 5-3: Attributes of the Metadata collection Tag

Attribute

Description

Values

Required

Default

element-type

Name of the class for the collection's elements.

Text

No

Implied

embedded-element

Is the element embedded?

"true", "false"

No

Implied

The value of the element-type attribute may be a fully qualified class name, or starting with JDO 1.0.1, it may be relative to the package name of the application data class. If the attribute is omitted, its implied value is "java.lang.Object".

The embedded-element attribute takes a value of either "true" or "false". Its implied value is "false" for application data classes, the Object class, and interface types, and "true" otherwise. The implied value is a directive for the JDO implementation, and the opposite value is a hint on how to store and manage the elements of the collection. When the value is "true" and the hint or directive is followed, the elements are stored as part of the collection. Deleting the collection, which happens implicitly as the result of deleting the application data object that refers to the collection, causes JDO to delete the elements of the collection. When the value is "false" and the hint or directive is followed, deleting the collection does not delete the elements of the collection. As with the embedded attribute of the field tag, changing the implied value is not well supported, and whenever possible should be avoided.

The following example identifies the element type of a collection field as the application data class Book. Because the example omits the embedded-element attribute, it accepts the implied value of "false". The package of the Book class is the same package named by the enclosing package tag.

 <collection element-type="Book" /> 

The map Tag

Like the collection tag, the optional map tag is usually not omitted for a field that is a map type, e.g., Map, TreeMap, HashMap, and Hashtable. The JDO implementation can usually do a better job of managing the Map field if it knows the specific types of the collection's keys and values. Table 5-4 describes the four optional attributes of the map tag.

Table 5-4: Attributes of the Metadata map Tag

Attribute

Description

Values

Required

Default

key-type

Name of the class for the map's keys.

Text

No

Implied

embedded-key

Is the key embedded?

"true", "false"

No

Implied

value-type

Name of the class for the map's values.

Text

No

Implied

embedded-value

Is the value embedded?

"true", "false"

No

Implied

The values for the key-type and value-type attributes may be fully qualified class names, or starting with JDO 1.0.1, they may be relative to the package name of the application data class. If either attribute is omitted, its implied value is "java.lang.Object".

The two optional attributes embedded-key and embedded-value take a value of either "true" or "false". The preceding discussion of the embedded-element attribute in the collection tag applies to these two attributes as well.

The following example identifies the key-type and value-type of a map field. The example accepts the implied value of "true" for the embedded-key attribute and the implied value of "false" for the embedded-value attribute.

 <map key-type="java.lang.String" value-type="Book" /> 

The array Tag

Unlike the collection and map tags, the array tag can often be omitted for array fields. The array tag takes one optional attribute, the embedded-element attribute, which is either "true" or "false". The preceding discussion of the embedded-element attribute in the collection tag applies to this attribute as well.

The extension Tag

Every tag in the JDO metadata, including extension tags, can contain zero or more extension tags. Vendors use the extension tag to provide additional information that is helpful to the implementation. Table 5-5 describes the three attributes of the extension tag.

Table 5-5: Attributes of the Metadata extension Tag

Attribute

Description

Values

Required

Default

vendor-name

Vendor-specific string

Text

Yes

No default

key

Part of key-value pair

Text

No

Vendor specific

value

Part of key-value pair

Text

No

Vendor specific

The extension tag requires a vendor-name attribute and allows optional key and value attributes. This tag's structure is intended to be flexible. An implementation ignores the extension tags that are not its own. The next section provides an example that uses the extension tag.

An Example of a Complete Metadata File

Listing 5-5 shows a complete metadata file for the library example available from the Apress Web site (http://www.apress.com) and at SourceForge.net (http://sourceforge.net). The library example is one of the JDO Learning Tools that allows you to explore JDOQL queries.

Listing 5-5: The JDO Metadata for the Library Example

start example
 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jdo PUBLIC       "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 1.0//EN"       "http://java.sun.com/dtd/jdo_1_0.dtd"> <jdo>    <package name="com.ysoft.jdo.book.library">       <class name="Borrower" identity-type="datastore" >          <field name="oidString" persistence-modifier="none" />          <field name="books" >             <collection element-type="com.ysoft.jdo.book.library.Book" />             <extension vendor-name="kodo" key="inverse" value="borrower"/>          </field>       </class>       <class name="Book" identity-type="datastore" >          <field name="oidString" persistence-modifier="none" />          <field name="borrower" />          <field name="categories" >             <collection element-type="com.ysoft.jdo.book.library.Category" />             <extension vendor-name="kodo" key="inverse" value="books"/>          </field>       </class>       <class name="Category" identity-type="datastore" >          <field name="oidString" persistence-modifier="none" />          <field name="books" >             <collection element-type="com.ysoft.jdo.book.library.Book" />             <extension vendor-name="kodo" key="inverse" value="categories"/>          </field>       </class>       <class name="Volunteer" identity-type="datastore" >          <field name="oidString" persistence-modifier="none" />       </class>    </package> </jdo> 
end example

This example has only one package that contains application data classes. Within the package there are four application data classes: Book, Category, Borrower, and Volunteer. Each of the application data classes has one unmanaged field. Most have a HashSet field for which the collection tag is provided. Several of the persistent fields in these application data classes are not mentioned in the metadata because the implied values are the values desired.

The metadata in Listing 5-5 is configured for Kodo, as indicated by the use of "kodo" in the extension tag's vendor-name attribute, but it can be used as is with other implementations. JDO requires that implementations ignore the extension tags that are not their own.

The metadata in Listing 5-5 is configured for JDO 1.0. As a result, it lists the fully qualified names for the element-type attributes even though the JDO 1.0-compatible versions of Kodo implement the JDO 1.0.1 naming conventions.

During development, while the application data classes are changing, the programmer must make concurrent changes in the metadata file. After development, porting a metadata file from one implementation to the next involves only the extension tags. If desired, the extension tags for the prior implementation can be left in while new extension tags for the next implementation are added.




Using and Understanding Java Data Objects
Using and Understanding Java Data Objects
ISBN: 1590590430
EAN: 2147483647
Year: 2005
Pages: 156
Authors: David Ezzio

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net