Multi Src Field Mapping

This mapping provides a way to map multiple database fields to one field in the object model. If the field is loaded, the related fields are load from the database and the contents are stored in a java.util.Map . An exchange operation, which is defined as part of the mapping metadata, is supposed to create the resulting content, which is stored in the object model. A similar mechanism is implemented for storing the data. Because the values as used in the object model are mostly not recognizable in the datastore, querying for fields mapped by the MultiSrcField mapping is not supported.

MultiSrcField mapped fields are treated similar to direct mapped fields. Because of the user specified exchange operation, object fields mapped by MultiSrcField mapping can be any type desired. The used type should be an descendent from java.lang.Object . Primitive datatypes are not easily supported by the exchange operation mechanism. The class, which is used as the type of a MultiSrcField mapped field does not need to be enhanced.

In order to map a field with MultiSrcField mapping, the following information are necessary:

The following example shows how to use MultiSrcField mappings. As container object we use the class Person , which has a field birthday of the type java.util.Date . In the datastore the date is stored in separate fields for the day, the month and the year of the date. This gives us the following class:
import java.util.Date;

public class Person {
..
  private Date birthDate;

  public Date getBirthDate ()
  {
    return birthDate;
  }
...
  public void setBirthDate (Date value)
  {
    birthDate = value;
  }

}

Additionally we have to create an exchange operation. This class should implement the interface com.signsoft.ibo.jdbc.ExchangeOperation , an example implementation is shown below:

public class DateExchangeOperation implements ExchangeOperation
{
  public DateExchangeOperation() { }

  public void init(Properties p) throws ExchangeException {}

  public Object toDatabase(Object o) throws ExchangeException
  {
    if (o == null) return null;
    if (!(o instanceof Date)) return null;

    Map ret = new HashMap();
    Calendar cal = Calendar.getInstance();
    cal.setTime((Date) o);

    ret.put ("day", new Integer(cal.get(Calendar.DAY_OF_MONTH)));
    ret.put ("month", new Integer (cal.get(Calendar.MONTH)));
    ret.put ("year", new Integer (cal.get(Calendar.YEAR)));

    return ret;
  }

  public Object fromDatabase(Object o) throws ExchangeException
  {
    if (o == null) return null;
    if (!(o instanceof Map)) return null;

    Calendar cal = Calendar.getInstance();

    Map container = (Map) o;

    int day = ((Number) container.get("day")).intValue();
    int month = ((Number) container.get("month")).intValue();
    int year = ((Number) container.get("year")).intValue();

    cal.set(year, month, day);

    return cal.getTime();
  }
}

To map this for usage with Signsoft intelliBO, we define the field birthDate of class Person as persistent, with an MultiSrcField mapping. You have to explicitly specify the database fields and their corresponding names for the data conversion map.

A possible mapping is shown here:

<?xml version="1.0" encoding="UTF-8"?>
<jdo xmlns="http://java.sun.com/xml/ns/jdo/jdo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/jdo/jdo http://java.sun.com/xml/ns/jdo/jdo_2_0.xsd">

  <package name="com.signsoft.ibo.sample">
    <class identity-type="datastore" name="Person">
      <field default-fetch-group="true" name="birthDate">
        <extension key="jdbc" vendor-name="ssibo">
          <extension key="mapping" value="multi-src-field" vendor-name="ssibo">
            <extension key="exchange-operation"
             value="com.signsoft.ibo.sample.DateExchangeOperation" vendor-name="ssibo"/>

            <extension key="field" vendor-name="ssibo">
              <extension key="field-name" value="day" vendor-name="ssibo"/>
              <extension key="db-field-name" value="FDAY" vendor-name="ssibo"/>
            </extension>

            <extension key="field" vendor-name="ssibo">
              <extension key="field-name" value="month" vendor-name="ssibo"/>
              <extension key="db-field-name" value="FMONTH" vendor-name="ssibo"/>
            </extension>

            <extension key="field" vendor-name="ssibo">
              <extension key="field-name" value="year" vendor-name="ssibo"/>
              <extension key="db-field-name" value="FYEAR" vendor-name="ssibo"/>
            </extension>

          </extension>
        </extension>
      </field>
 ...
    </class>
  </package>
</jdo>

In your application, you may use a field mapped by MultiSrcField mapping as any other direct mapped field, e.g. like the following:

...
  Person p = new Person();
  Date d = new Date();
  p.setBirthDate(d);

  pm.makePersistent(p);
...