Introduction Application types Compound types
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. |