4.2. Mapping Attributes


Contents

4.2.1. Attribute Types

4.2.2. Simple Attributes

4.2.3. Relationship Attributes

4.2.4. The Attribute Mapping Form

4.2.4. Relationship Examples


This section discusses how to map the attributes of a persistent class to columns in a relational database.

 

4.2.1. Attribute Types

There are two types of attributes that can be defined in a persistent class:

  1. Simple Attributes. A Simple attribute holds a value of a specific type such as an integer or a date.
  2. Relationship Attributes. Relationship attributes hold a direct reference to another object or to a collection of objects.

 

4.2.2. Simple Attributes

VBSF allows you to define simple attributes of the following types:

INTEGER. Holds integer values and maps to:

LONG. Holds large integer values and maps to:

FLOAT. Holds single precision floating point types and maps to:

DOUBLE. Holds double precision floating point types and maps to:

STRING. Holds text and maps to:

BOOLEAN. Holds a true or false value and maps to:

DATE. Holds date and time values and maps to:

BIGDECIMAL. Holds large integer values and maps to:

MEMO. Holds large amounts of text and maps to:

BLOB. Holds large binary data, such as images or sounds, and maps to:

BINARY. Holds small binary data, such as a binary UUID, and maps to:

CONTAINED OBJECT. Holds an embedded Java object that maps to multiple columns, and maps to:

For an example of a CONTAINED OBJECT attribute in a SUBSET class, refer to the Phone class and the myPhone attribute of the Employee class in the vemployeedemo sample application. For an example of a CONTAINED OBJECT attribute in a SUPERSET class, refer to the Country class and the country attribute of the InternationalPhone class in the vcontactdemo3 sample application.

CONTAINED BLOB OBJECT. Holds an embedded Java object that is automatically serialized and de-serialized to a binary column, and maps to:

For an example of a CONTAINED BLOB OBJECT attribute, refer to the Address class and the myAddress attribute of the Employee class in the vemployeedemo sample application.

OBJECT. Holds any other type of data, and its actual RDBMS column and Java data types vary. This type is provided to support any database specific data types that maybe returned when using the getObject()/setObject() methods provided in JDBC to get and set the value of the column.

 

4.2.3. Relationship Attributes

VBSF allows you to define of the following two relationship attribute types:

REFERENCE

Reference attributes hold a direct reference (to-one relationship) to another object of the same or different class type. The Java data type of a REFERENCE attribute may be any of the following:

  1. OReference. OReference is a VBSF class type that transparently provides lazy retrieval of the object referenced from the database and is fully serializable. Most of the sample applications use this option. For details on the OReference class see the Programmer's Guide.
  2. The referenced type. For example, if an object of type Customer is being referenced in an Invoice object, the REFERENCE attribute in the Invoice class may be defined as Customer. The drawback to this approach is that lazy retrieval is not supported, so each time an Invoice object is instantiated, its referenced Customer object is also instantiated. This could result in multiple queries to the database if the Customer object is not already in the cache.  See the companydemo2 sample application for details.
  3. A referenced application specific interface. This allows your persistent classes to be fully decoupled from VBSF by not using the OReference class, while still taking advantage of the lazy retrieval capabilities of the OReference class. For example, if an object of type Customer is being referenced in an Invoice object, and the Customer class implements an ICustomer interface, then the Java data type of the REFERENCE attribute in the Invoice class may be defined as ICustomer. The only drawbacks to this approach is that it requires each referenced class to implement an interface that mirrors the class signature and support for this feature requires a 1.3.x JVM. See the vposdemo sample application for an example of using this option.
  4. Not an attribute.  Using the example above, the Invoice class does not have an attribute to reference its Customer object. Instead, the getReference and  setReference methods of the Database class are used by the client or the to Invoice object itself to fetch the referenced object when necessary. This option does not suffer from any of the above drawbacks.  See the posdemo2 sample application for details.

 

REFERENCED COLLECTION

A referenced collection attribute type is used to define to-many relationships. Referenced collection attributes hold a collection of objects of the same class or of multiple classes. VBSF supports two types of collection attributes:

  1. Owned Collection. Holds a collection of persistent objects owned by the persistent class that holds the collection..
  2. Referenced Collection. Holds a collection of objects owned by another persistent class, or not owned by any other classes (i.e. root classes).

VBSF also supports homogeneous (one class) and heterogeneous (multiple class) collections. Heterogeneous collections can be defined by specifying a superclass name (in which case objects from any of its subclasses can be part of the collection), an interface name (objects from any classes that implement that interface can be part of the collection), or multiple class names (objects from any of the classes named can be part of the collection). For details on heterogeneous collections see section 8. Heterogeneous Collections.

The Java data type of a REFERENCED COLLECTION attribute may be any of the following:

  1. OCollection. OCollection is a VBSF class type that transparently provides lazy retrieval of the objects in the collection from the database and is fully serializable. Most of the sample applications use this option. For details on the OCollection class see the Programmer's Guide.
  2. Collection. This type allows you to define the collection as the standard java.util.Collection interface. The java.util.Collection interface is implemented by the VBSF OCollection class. That allows your persistent classes to be fully decoupled from VBSF while still taking advantage of the lazy retrieval capabilities of the OCollection class. The only drawback to this approach is that you are limited to the collection operations defined in the standard java.util.Collection interface. However, you may cast the collection back to an OCollection at any time to take advantage of its rich set of collection operations. See the vposdemo sample application for an example of using this option.
  3. An array or Vector of the referenced type. For example, if a collection of LineItem objects are being referenced by an Invoice object, the REFERENCE COLLECTION attribute in the Invoice class may be defined as LineItem[]. The drawback to this approach is that lazy retrieval is not supported, so each time an Invoice object is instantiated, its referenced LineItem objects are also instantiated. This could result in multiple queries to the database if the LineItem objects are not already in the cache. When using this option you must use the addToCollection and removeFromCollection methods of the Database class at runtime to add and remove objects from the collection. If you use a Vector data type, and add or remove objects directly to or from the Vector, you must still use the  addToCollection and removeFromCollection methods to keep VBSF informed of changes to the collection. See the companydemo2 sample application for details.
  4. Not an attribute.  Using the example above, the Invoice class does not have an attribute to reference its LineItem objects. Instead, the get and  list methods of the Database class that accept a collection name are used by the client or the to Invoice object itself to fetch the referenced objects when necessary. This option does not suffer from any of the above drawbacks. When using this option you must use the addToCollection and removeFromCollection methods of the Database class to add and remove objects from the collection.  See the posdemo2 sample application for details.

 

4.2.4. The Attribute Mapping Form

This section deals with the Attribute Mapping Form which is shown on the right hand side of the split pane whenever a class attribute object is selected in the tree. This form is used to specify all mapping information pertaining to a persistent class attribute. The Attribute Mapping Form is divided into three tabbed panels: General, Mappings, and Relationship.

 

General Panel

The General panel is used to specify the attribute type, its properties, and the type of access. Information for a simple attribute of type LONG is shown below:

mtidatr.jpg (97005 bytes)

You can specify the following options:

Attribute Type. Select the VBSF attribute type.

Java data type. Enter, or select from the combo box drop down list, the Java data type to be used for this attribute. This field is automatically assigned the default Java data type specified in the Configuration Dialog Box. corresponding to the Attribute Type selected. For REFERENCE attributes you may select 'OReference' or 'Referenced Type', enter the name of an interface implemented by the referenced class, or leave the Java dada type blank to specify that the relationship is not an attribute. For REFERENCED COLLECTION attributes you may select 'OCollection', 'Collection', 'Array' or 'Vector', or leave the Java dada type blank to specify that the relationship is not an attribute. Recommended Java data types for simple attributes are listed in section 4.2.2. Simple Attributes.

Properties Panel

Object ID. Check this option if the attribute is the object ID, or part of the object ID. You must define at least one of the attributes in the persistent class as the object ID. Persistent objects must be identifiable by a unique object ID. An object ID usually needs only to be unique within a business class (i.e two objects can have the same ID as long as they belong to different business classes). An object ID can be made up of only one attribute mapped to a column, or of multiple attributes each mapped to a column. If the object ID is made up of multiple attributes, the combination of all attribute values must be unique. The object ID attribute should be mapped to the table's primary key column, or at least to a column which has a unique index. Multi-attribute object IDs should be mapped to a compound primary key. Using a primary key as the object ID has several advantages:

VBSF supports many methods for automatic object ID generation for classes with only one object ID attribute. For details see the next section 4.4. ID Generation Methods.

Disable Concurrency Control. Check this option to disable concurrency control for this attribute. By default VBSF checks that every attribute, except MEMO, BLOB and CONTAINED BLOB OBJECT attributes, that has changed has not been altered by another user when writing changes to the database. Sometimes, however, it is not desirable to check all attributes that have changed, but instead only certain 'critical' attributes. Depending on the database, the JDBC driver and the attribute data type it may also be necessary to check this option if updates to the database do not succeed because the precision of the original value of the attribute is lost. One example is DATE attributes in SQL Server 7.0 with the Java 1.2.2 JDBC/ODBC bridge as the driver. This could also happen with floating type attributes. If it is not necessary to check whether this attribute has been modified by another user, check this option. This option is ignored if a dedicated concurrency column is defined for the persistent class. See section for 4.4. Filter and Concurrency Columns details.

Indexed. Check this option if the attribute will be indexed. Attribute indexes are used to create corresponding column indexes during DDL script generation, and to speed up in-memory queries containing query parameters with EQUAL comparisons. In order for the in-memory query processor to be able to use attribute indexes it is also necessary that all query fields be joined with the AND logical operator and that at least one query attribute be indexed, or, that all query fields be joined with the OR logical operator and that all query attributes be indexed. This option is automatically disabled  for the object ID attribute since VBSF indexes the ID automatically. Since maintaining indexes does require some system overhead, use this method only if objects will be retrieved by attribute name often, and there is a significant number of objects such that index lookup is faster than an object collection scan. Note that there is a significant overhead in maintaining an index when an element is deleted from a class extent or removed from a collection, therefore it is not recommended that this option be enabled (except temporarily for database index generation in the DDL script) for any class with a large extent for which there will be frequent deletion or removal of objects.

Type of Access Panel

Direct Variable Access. Enable this option if the persistence layer sets and gets the value of this attribute using direct object member access. This is the default option.

Access via get/set methods. Enable this option if the persistence layer sets and gets the value of this attribute using get and/or set methods. This provides the object control and notification of when the attribute is set or read by the persistence layer. When enabling this option you must specify either the name of the get or the set method, or both.

Get. If Access via get/set methods is enabled, enter the name of the get method without any arguments.

Set. If Access via get/set methods is enabled, enter the name of the set method without any arguments.

No indexing. If the attribute is accessed via get/set methods and this option is enabled, the persistence layer assumes the get method does not accept any arguments and that the set method accepts the value of the attribute as argument. This is default option. See the employeedemo and companydemo2 sample applications for examples.

Index by attribute name. If the attribute is accessed via get/set methods and the attributes are kept in an string indexable structure such as a Hashtable, VBSF can provide to the get and set method the name of the attribute as argument if this option is enabled. Normally this option is set programmatically. See the Customer class in the posdemo2 sample application for details.

Index by number. If the attribute is accessed via get/set methods and the attributes are kept in an ordinal indexable structure such as a Vector, VBSF can provide to the get and set method an index number as argument if this option is enabled. Normally this option is set programmatically.

Index number. If Index by number is enabled, enter this attribute's index number. Normally this option is set programmatically.

 

Mappings Panel

The Mappings panel is used to specify database mappings and information related to the value of the attribute. This panel is disabled for attributes of type REFERENCED COLLECTION. Mappings for a simple attribute of type STRING is shown below:

mtatr02.jpg (93305 bytes)

Database Mapping Panel

Table. If the persistent class the attribute belongs to has a SUPERSET mapping, enter, or select from the combo box drop down list, the name of the table where this attribute can be found. Otherwise this field is disabled. Table names are case sensitive, therefore all references to the same table name throughout the schema must use the same capitalization.

Column. Enter, or select from the combo box drop down list, the name of the column where the attribute will be stored. The column name must be specified for both simple attributes and REFERENCE attributes. Column names are case sensitive, therefore all references to the same column name throughout the schema must use the same capitalization. If the attribute is a REFERENCED COLLECTION, then this field is disabled. If the attribute is a REFERENCE mapped to a composite foreign key (i.e., multiple foreign key columns) because the reference points to a class mapped to a table with a composite primary key, then you must enter multiple column names separated by a comma. For an example of multi-column references, refer to the vcontactdemo3 sample application.

Data Type. This setting is only used when generating a DDL script from the schema. Enter the column data type. If the attribute is a REFERENCE mapped to a composite foreign key, then you must enter multiple data types separated by a comma. If you leave this field blank and generate a DDL script, the script generator will obtain the default column data type for the current attribute type from the DB Type Mappings panel of the configuration dialog box. If that value is also blank, the script generator will display an error message. For string and numeric attributes you may directly specify the size or precision in this field, or you may instead use the Max Size. field of the Value panel combined with the size marker. When generating multiple DDL scripts against different target databases it may be useful to always leaving this field blank, and instead specify all column data types in the DB Type Mappings panel of the configuration dialog box. However, it may be necessary to specify the data type of special column types, such as auto-incrementing columns mapped to ID attributes. For example, in MS SQL Server you would enter 'INTEGER IDENTITY' as the data type of an auto-incrementing column.

Nullable. This setting is only used when generating a DDL script from the schema. Check this option if the column is nullable.

Unique. This setting is only used when generating a DDL script from the schema. Check this option if the column is unique.

LOB. Enables support for CLOB and BLOB SQL data types for databases that support them, such as Oracle, DB2 and Informix. If the attribute will be stored in a CLOB or BLOB column, then check this option. Note that the maximum LOB size VBSF supports is 2147483647 (Integer.MAX_VALUE). This feature requires the use of a JDBC 2.0 compliant driver and is only enabled if the VBSF attribute type is MEMO or BLOB.

Value Panel

Default. Enter a default value for this attribute. This default value will be automatically assigned to the attribute when VBSF is used to construct objects of the class.

Validity Check. Enter, or select from the combo box drop down list, a validity check for this attribute. An attribute validity check allows you to set and enforce a set of parameters that define the validity of an attribute value such as a maximum value, minimum value, set of valid values, etc. For details on defining validity checks see section 6. Attribute Validity Checks.

Max Size. For STRING attributes this option specifies the maximum size of the attribute. For BIGDECIMAL attributes this option specifies the scale, or number of decimal digits to the right of the decimal point. This setting is very important for BIGDECIMAL attributes if you are using a JDBC 1.x driver, and leaving it blank will most likely result in loss of precision or update conflict exceptions. Note that when using a JDBC 2.0 driver, this field may be left blank for BIGDECIMAL attributes. The size is also used as the column size or precision when generating a DDL script and the size marker is encountered.

Enforce Size. Check this option if the attribute is of type STRING and you want VBSF to throw a validity check exception if the actual attribute string size is larger than the maximum size. This will avoid data loss when saving to the database, since most drivers will simply truncate excess data when storing data in the text column.

 

Relationship Panel

The Relationship panel contains information about attributes that define relationships to other classes. This panel is disabled for simple attributes.

mtcolatr02.jpg (93025 bytes)

Referenced Class. Enter, or select from the combo box drop down list, the fully qualified name of the class this attribute is referencing. If the Heterogeneous option is checked, you can enter  the name of a superclass (in which case objects from any of its subclasses can be referenced if the attribute is of type REFERENCE, or be part of the collection if the attribute is of type REFERENCED COLLECTION), or an interface name (in which case objects from any classes that implement that interface can be referenced or be part of the collection). If the attribute is of type REFERENCED COLLECTION you can also enter multiple class names separated by a space or comma.

Referenced Attribute. Enter, or select from the combo box drop down list, the name of the attribute of the referenced class (i.e. the one specified in the Class field) that this relationship attribute will join with. If the attribute is of type REFERENCE, you may leave this field blank to specify that the referenced attribute is the object ID of the referenced class. However, if the attribute is of type REFERENCE and is mapped to a composite foreign key (i.e., multiple columns are mapped to the attribute), then you must leave this field blank. If the attribute type is Owned Collection (i.e. its type is REFERENCED COLLECTION and the Owned option is checked) leave this field blank to specify the object ID of the referenced class, or enter the name of the attribute referenced in the referenced class. If the attribute type is Referenced Collection (i.e. its type is REFERENCED COLLECTION and the Ownership option is NOT checked) you must either enter the name of the attribute to join with in the referenced class (even if it is the object ID), or map the attribute to a join table. If the attribute is a Referenced Collection that is mapped to a join table, this field must be left blank.

Properties Panel

Ownership. This option determines whether the relationship is an ownership (aggregation) or an acquaintance (association). Check this box to specify an ownership relationship. Owned collections (REFERENCED COLLECTION attributes with this option checked) are automatically updated in the database when the owner of the collection is updated in the database, although this behavior can be overridden at runtime. This option must be set identically on both sides of the same relationship.

Contained Reference. Check this option if the attribute is a contained reference. Contained references are automatically updated in the database when the holder of the reference is updated in the database, although this behavior can be overridden at runtime. This option is only enabled if the attribute is of type REFERENCE. The Ownership option and this option are mutually exclusive, checking one automatically removes the checkmark in the other.

Shallow Retrieval. This option determines whether object references are obtained when the holder of the reference is instantiated (deep), or when the referenced object(s) is(are) actually accessed (shallow). Shallow retrieval is recommended. Relationship attributes with a defined Java data type of 'Referenced Type', 'Array', or 'Vector' are automatically instantiated when the holder of the reference is instantiated regardless of how this option is set.

Heterogeneous. Check this option if the object(s) referenced can be of more than one type (i.e. can belong to more than one Java class). VBSF supports heterogeneous REFERENCED COLLECTION attributes that maintain a collection of multiple classes, and heterogeneous REFERENCE attributes that can maintain a reference to multiple classes as long as all possible referenced classes extend the same superclass, or implement the same interface.

Join table manager. Check this option if the attribute is mapped to a join table and this class is the join manager responsible for updating the join table. An attribute can only be mapped to a join table if it is a Referenced Collection attribute (i.e. its type is REFERENCED COLLECTION and the Ownership option is NOT checked). When two classes are related via join table, at least one of the classes must be designated as the join manager. The join manager has no functionality in the object model. It is simply a designation that tells VBSF which persistent class updates the join table when it is updated in the database. The choice of a join manager is arbitrary. 

Note that it is acceptable to specify both persistent classes in the relation as join managers of the join table, but this option should be used with care as it could result in duplicate row insertions in the join table. For example, if there are two classes A and B in a many-to-many relation mapped to a join table, then adding a B to A.myBs and adding an A to B.myAs, and then updating both A and B in the database will result in duplicate rows in the join table if both classes were defined as the join table managers. However, if each class is added to the other's collection is different sections of your application, then this will not happen.

This option is enabled only if the attribute type is REFERENCED COLLECTION and the Ownership option is NOT checked. See section 4.6. Referenced Collection Joins for details on how to map a join table to a Referenced Collection attribute.

Owner may be left unspecified. If this attribute is a reference to the owner of this class (i.e. its type is REFERENCE and the Ownership option is checked), enabling this option allows you to save an object of the class without specifying its owner (e.g., with its foreign key set to null). This option is useful when the same class acts as both owner and owned. See the employeedemo sample application for details. Also, for REFERENCE attributes with a Java data type of 'Referenced Type', it may also be necessary to enable this option. For an example, refer to the vcompanydemo2 sample application.

 

4.2.5. Relationship Examples

Contactdemo Application Example

In the vcontactdemo sample application a Contact object maintains a collection of owned Address objects. This is done by defining an owned collection attribute in the Contact class. The two screens below shows how the currentAddresses owned collection attribute in the Contact class is defined:

mtcolatr.jpg (105900 bytes)

mtcolatr02.jpg (93025 bytes)

 

The Address class in turn maintains a reference to its Contact owner by defining a reference attribute as shown below:

mtrefatr01.jpg (98353 bytes)

mtrefatr02.jpg (90245 bytes)

 

VBSF is very powerful in its ability to traverse objects. You are not limited to traversing an object graph from the top down like you would have to in an object database. For example, in order to get a reference to an Address object you would normally need to have a reference to a Contact object first, and then ask the Contact object to provide you with a list of its Address objects. By defining a reference to its owner in the Address class we can perform ad-hoc queries on the Address class without regard for ownership, and then get a reference to an Address' owner. For example we could ask the Database to retrieve all addresses in San Francisco, CA, and then from each Address object obtain a reference back to its Contact owner object.

 

POS Application Example

The examples shown below demonstrate how to define relationships that use the standard java.util.Collection interface as the Java type for REFERENCED COLLECTION attributes and a referenced interface as the Java type for REFERENCE attributes. 

To specify the relationship between the Invoice and InvoiceLine classes described in the POS application illustrated in section 2.4. Mapping Object Relationships, the Invoice class would define the following attribute to access its line items:

lines Attribute
Form Field Setting
Attribute type REFERENCED COLLECTION
Java data type Collection
Class vposdemo.engine.InvoiceLine
Attribute <leave blank>
Ownership Checked

The InvoiceLine class in turn would define the following attribute to link it back to its owner:

myOwner Attribute
Form Field Setting
Attribute type REFERENCE
Java data type vposdemo.engine.IInvoice
Column InvoiceID
Class vposdemo.engine.Invoice
Attribute <leave blank>
Ownership Checked

The IInvoice type above is an interface implemented by the Invoice class. Notice that we must specify the foreign key column name for attributes of type REFERENCE. Also that both sides of the relation have the 'Ownership' option checked. In VBSF both sides of the same relationship must always have the same setting for the 'Ownership' option.

And to specify the to-one relationship between the Invoice and Customer classes described in the same application, the Invoice class would define the following attribute to access its customer object:

myCustomer Attribute
Form Field Setting
Attribute type REFERENCE
Java data type vposdemo.engine.ICustomer
Column CustomerID
Class vposdemo.engine.Customer
Attribute <leave blank>
Ownership Not Checked

The ICustomer type above is an interface implemented by the Customer class.

 

 

Next Section 

Return to Table of Contents