##### General information

- Overview
- News and Status
- Downloads
- Addons
- Changes
- Old Changes
- Wiki
- Issue tracker
- Mailing lists
- Tools
- License
- Team
- Developer Information
- Sponsorship
- Security
- Thanks

##### Documentation

- Tutorial
- OR Mapping Reference
  - Defining the Schema
  - Running the Generator
  - Database independence
  - Initialisation of the Runtime
  - Reading from the DB
  - Writing to the DB
  - Extending classes
  - Connections and Transactions
  - Exception handling
  - Inheritance
  - Supported databases
  - Supporting a new DB
  - Managers and Cache
  - Beans
  - Avalon Component
  - Customizing the generation
  - Relevant classes
  - Source XSD
  - Source XSD (strict)
  - Migration from Torque 3
- Code Generation Reference
- Module Documentation

##### Previous releases

- Torque 3.3

## Extending the Base Classes

Much of the power of Torque stems from the fact that you can easily add to and change the behavior of the generated classes by adding or overriding methods.

To keep your own code changes apart from the generated code, Torque provides two classes of a kind for each table:

- The Base... classes are overwritten each time you regenerate the classes from the schema and contain all functionality provided by Torque.
- The non-base classes inherit from their respective Base Classes, but are empty initially. They are not overwritten if you regenerate the classes from the schema. All code which you add to the data model should go into the non-base classes.

## Adding Methods to Peers

Adding methods to Peers will be one of the most common things you will do while using Torque. For example, if you want to retrieve objects from the database without creating a Criteria objects, you would typically add a corresponding method to the Peer class.

As an example, consider the bookstore example from the Tutorial. If you often retrieve Books by their ISBN number, you would add the following method to the BookPeer class:

    public static List<Book> doSelectByISBN(String isbn)
    {
        Criteria crit = new Criteria();
        crit.add(BookPeer.ISBN, isbn);
        List<Book> books = BookPeer.doSelect(crit);
        return books;
    }

## Adding Methods to the PeerImpl classes

If you use the delegation approach of the Peer/PeerImpl classes to exchange the implementation of the Peer classes (e.g. by inserting mocks for component tests), or if you use the PeerImpl classes directly (e.g. in a dependency injection framework), you can also make the changes/additions to the Peer classes in the PeerImpl classes. If you add a method in the first case, you should also add a delegation method to the Peer class.

Since adding delegation methods is cumbersome, we recommend to add code to the Peer class instead of the PeerImpl class if you do not have a reason to decide otherwise (like one of the above reasons).

## Adding Methods to Data Objects

By adding methods to Data Objects, you can add additional behaviour to the data objects. For example, you might want to order authors by their name in memory. To do this, you could make the authors implement the Comparable interface and add a compareTo Method:

    public class Author
        extends org.apache.torque.test.BaseAuthor implements Comparable<Author>
    {
        public int compareTo(Author other)
        {
            // null handling omitted for simplicity
            return getName().compareTo(other.getName());
        }
    }

Then you can sort the authors by name by calling the Collections.sort method.

To change the behavior of the generated classes, you can override an existing method in a generated class. For example, if you decide to add validation code to an author in order not to allow blank author names, you can override the setter method for the name:

    import org.apache.commons.lang.StringUtils;

    public class Author
        extends org.apache.torque.test.BaseAuthor
    {
        @Override
        public void setName(String name)
        {
            // accept blank names which are already in the database
            if (!isLoading())
            {
                if (StringUtils.isBlank(name))
                {
                    throw new IllegalArgumentException(
                        "author name must not be blank");
                }
            }
            super.setName(name);
        }
    }

## Adding Methods to Record mappers

Adding methods to or overriding methods in the RecordMapper class will not often occur in practice. Still, it can be done and should be done if the need arises.