# Nested Attributes

## Introduction

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:

    <field name="address.country.code"...>
      <sql name="person_country"/>
    </field>

## Application types

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.

Assume that you have the class Address

    public class Address {
        private CountryCode _country;
        private String      _city;
        private String      _street;

        public CountryCode getCountry() {
            return _country;
        }

        public void setCountry(CountryCode country) {
            _country = country;
        }
        ...
    }

where the class CountryCode is like this

    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() {
        ...
    }

then write in the configuration file:

    <class name="Address"...>
      <field name="country.code"...>
        <sql name="addr_country"/>
      </field>
      ...
    </class>

When reading the object from the database Castor will use

    object.getCountry().setCode(value);

to set the nested attribute value. Moreover, if object.getCountry() is null, Castor will create the intermediate object of the application type:

    country = new CountryCode();
    country.setCode(value);
    object.setCountry(country);

When writing the object to the database Castor will use

    value = object.getCountry().getCode();

to get the value of the correspondent database field.

## Compound types

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:

    public class Person {
        private String  _firstName;
        private String  _lastName;
        private Address _address;

        public Address getAddress() {
            return _address;
        }

        public void setAddress(Address address) {
            _address = address;
        }
        ...
    }

where the class Address is the same as in the previous section. Then write in the configuration file:

    <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>

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.