<?xml version="1.0" encoding="ISO-8859-1"?>
<document url="http://castor.org/nested-attr.xml">
  <body>
    <title>Nested Attributes</title>


    <section title="Introduction">
     <p>In some cases it is desirable to map a plain sequence of fields
        in a database record to more complicated structure of attributes
        in a Java object, where the target attributes are contained (nested)
        in other attributes.
        In brief, you can specify a path to the target attribute as a name 
        of the field in a configuration file, and Castor is able to handle
        such nested attributes.
        For example:
          <code><![CDATA[
      <field name="address.country.code"...>
        <sql name="person_country"/>
      </field>]]>
          </code>
     </p>
    </section>

    <section title="Application types">
     <p>The first case is an attribute of an application type that is 
        a container for some value of a Java type supported by Castor.
        Usually the application type also has some business methods. 
        Examples are: class Balance that contains a BigDecimal value and 
        has some accounting-specific methods; 
        class CountryCode that contains a String value and has 
        methods validate(), getDisplayName(), etc.; class Signature that 
        contains a byte[] value and has some security-specific methods. 
        In order to use such type with Castor you should provide 
        a pair of methods to get/set the value of the Castor-supported type, 
        e.g. getBigDecimal/setBigDecimal, getCode/setCode, getBytes/setBytes. 
     </p>
     <p>Assume that you have the class Address
        <pre>
        public class Address {
            private CountryCode _country;
            private String      _city;
            private String      _street;

            public CountryCode getCountry() {
                return _country;
            }
        
            public void setCountry(CountryCode country) {
                _country = country;
            }
            ...
        }
        </pre>
        where the class CountryCode is like this
        <pre>
        public class CountryCode {
            private String _code;
            private static String[] _allCodes;
            private static String[] _allDisplayNames;

            public String getCode() {
                return _code;
            }
        
            public void setCode(String code) {
                _code = code;
            }

            public void getDisplayName() {
            ...
        }
        </pre>
        then write in the configuration file:
          <code><![CDATA[
    <class name="Address"...>
      <field name="country.code"...>
        <sql name="addr_country"/>
      </field>
      ...
    </class>]]>
        </code>
        When reading the object from the database Castor will use
        <pre>
        object.getCountry().setCode(value);
        </pre>
        to set the nested attribute value.
        Moreover, if object.getCountry() is null, Castor will create the 
        intermediate object of the application type:
        <pre>
        country = new CountryCode();
        country.setCode(value);
        object.setCountry(country);
        </pre>
        When writing the object to the database Castor will use
        <pre>
        value = object.getCountry().getCode();
        </pre>
        to get the value of the correspondent database field.
     </p>
    </section>

    <section title="Compound types">
     <p>The second case is an attribute that is a part of a compound 
        attribute, which contains several database fields.
        For example, database fields person_country, person_city, 
        person_street of the table PERSON correspond to one compound 
        attribute "address" of the class Person:
        <pre>
        public class Person {
            private String  _firstName;
            private String  _lastName;
            private Address _address;

            public Address getAddress() {
                return _address;
            }
        
            public void setAddress(Address address) {
                _address = address;
            }
            ...
        }
        </pre>
        where the class Address is the same as in the previous section.
        Then write in the configuration file:
          <code><![CDATA[
    <class name="Person"...>
      <field name="address.country.code"...>
        <sql name="person_country"/>
      </field>
      <field name="address.city"...>
        <sql name="person_city"/>
      </field>
      <field name="address.street"...>
        <sql name="person_street"/>
      </field>
      ...
    </class>]]>
        </code>
        Similarly to the previous section, Castor will use a proper 
        sequence of get/set methods to access the nested attributes and 
        will create the intermediate objects when necessary.
        Don't forget to provide parameterless constructors for the 
        container classes.
     </p>
    </section>

  </body>
</document>

