Torque HOWTO

LAST UPDATED: 2002-06-05 by Geoff Fortytwo (g42@_REMOVE_IF_NOT_SPAM_snowball.com)

Torque info links

Torque home page
Torque binary releases
how to use Criteria objects for more complex queries

What is Torque

Torque is a persistence layer. Torque generates classes which are used by your application to manipulate your DB tables.

In other words, you specify what DB tables you want to have, and it generates classes that you use to interact with those DB tables.

What is the latest version of Torque

As of 2002-05-27, the latest released version of Torque is called "torque-3.0-b2".

How to get started using Torque

In the following HOWTO, I use an example project called gamerprof (which stands for Gamer Profile) to illustrate how to use Torque. It's a very simple example. It is used simply to save and load information about the game preferences of multiple people (gamers).

To use Torque in a project you need to do the following:
 1. Set up the ID Broker (if you want to use it)
 2. Create an XML DB schema (for gamerprof it's "gamerprof-schema.xml").
 3. Create a Torque project properties file (for gamerprof it's "gamerprofTorqueBuild.properties").
 4. Modify the project's ANT build file to include the Torque stuff which generates the project
    Object Model (OM) java files.
 5. Create a Torque runtime properties file (for gamerprof it's "Torque.properties").
 6. Make sure that Torque is started before any DB access by putting the following in a static section
    of a class that'll always be loaded before any of the Torque generated classes are used:
        org.apache.torque.Torque.init(torquePropPath+"/Torque.properties");
    For gamerprof, that line is in a static section of the com.snowball.gamerprof.MainTest class.

 7. Add your own methods to the torque generated classes.

Set up the ID Broker

In the torque root directory, modify the build.properties so that the value of the "database" property specifies your DB type.

Go to the torque root directory and execute the following command:

    ant -buildfile build-torque.xml id-table-init-sql

It should have created the following file:
    {TORQUE_ROOT}/src/sql/{DATABASE}-id-table-init.sql

You can use that SQL to create the IDBROKER table which will be used to generate IDs for use as primary keys in your objects.

Create an XML DB schema

Here's the schema used by the gamerprof example: gamerprof-schema.xml

Create a Torque project properties file (for gamerprof it's "gamerprofTorqueBuild.properties")

The "project" property in the gamerprofTorqueBuild.properties file specifies what the schema xml file will be. So if the value of "project" in that properties file is "gamerprof" then the schema file will be called "gamerprof-schema.xml".

This properties file is referenced in the ANT "gamerprof-om" target of the build.xml file.

Modify the project's ANT build file to include the Torque stuff which generates the project Object Model (OM) java files.

Here's the ANT build target that's used to generate the object model classes for the gamerprof example using Torque. Once you've set this up, all you need to do is execute the following command: ant gamerprof-om (Obviously, the "gamerprof-om" would be different depending on what name you give the ANT target.) Take a look at the "gamerprof-om" target in the ANT build.xml file for the gamerprof example.

Create a Torque runtime properties file

This is used to initialize the Torque environment: Torque.properties

Add your own methods to the torque generated classes

After you run the ANT target, at least 5 files will be generated for every table in your DB schema.xml file. For instance, in the example gamerprof-schema.xml there's a description of the Game table:
  <!-- This describes a database table called "Game" which has 3 columns: id, title, tradeInPointWorth -->
  <table name="Game" javaName="Game" idMethod="none" skipSql="true">
    <!-- This column is an INTEGER. That means it is java type "int". It won't be "Integer", so any null
    values in an "INTEGER" column are returned as zeros (just like they are in JDBC if you call getInt()). -->
    <column name="id"                javaName="Id"                required="true" type="INTEGER" size="10"/>
    <!-- This represents a VARCHAR. That means it is java type "String". -->
    <column name="title"             javaName="Title"             required="true" type="VARCHAR" size="200"/>
    <column name="tradeInPointWorth" javaName="TradeInPointWorth" required="true" type="INTEGER" size="3"/>
  </table>  

Five files will be generated when the ANT target is run:

  BaseGame.java
    This contains the implementations all the accessor functions to this object (like getId(), getTitle(), etc.).
    This class is replaced every time the Torque ANT target is executed (In this case "ant gamerprof-om").
  BaseGamePeer.java
    This contains the implementations of various constants and static functions that are used to query, update,
    insert, and delete Game values in the corresponding DB table that the Game.java class represents.
    This class is replaced every time the Torque ANT target is executed (In this case "ant gamerprof-om").
  Game.java
    This is an empty class that's derived from BaseGame.
    This class is NOT replaced every time the Torque ANT target is executed (In this case "ant gamerprof-om").
    Torque only generates this class if it does not exist already.
  GamePeer.java
    This is an empty class that's derived from BaseGamePeer.
    This class is NOT replaced every time the Torque ANT target is executed (In this case "ant gamerprof-om").
    Torque only generates this class if it does not exist already.
  GameMapBuilder.java
    I don't really know what this class does. I've never needed to call any functions on it or make any
    modifications to it.
    This class is replaced every time the Torque ANT target is executed. (In this case "ant gamerprof-om")

Actually, a feature in Torque would optionally also create a GameManager.java file which would be used for caching. However, that feature is still considered experimental (as of 2002-05-27), so I don't use it.

MainTest.java contains some basic examples of how to use Game and GamePeer.

ADDITONAL NOTES

There's a lot of DB config info in the Torque config files, but the way I use Torque, I don't use the torque connection pool at all. Anytime a db connection is needed (meaning anytime I call a function on any of the generated *Peer classes), I create an instance of a wrapper class around a SimpleConnection. Here's the wrapper class:

DBConn.java

See GamePeer.java and Game.java for examples of how I use DBConn.

Until the next version of torque comes out, every time I generate the DB classes I need to do a recursive replace of
"BasePeer.doSelect" to "BasePeer.doPSSelect"
This makes all SELECT statements use prepared statements.

In the xml schema file for torque, any int field that may not contain null values can be of type "INTEGER". That way, the java type used will be "int". However, if you want to be able to retrieve or set null values in an int field then it needs to be type "NUMERIC". Those fields will be represented by the java type "BigDecimal". Hopefully in the next version they'll allow nulls in INTEGER fields.

The following is a list of allowed field types that can be used in the schema.xml file. I got it from the database.dtd file in the Torque distribution:

          BIT  | TINYINT | SMALLINT    | INTEGER    | BIGINT    | FLOAT
        | REAL | NUMERIC | DECIMAL     | CHAR       | VARCHAR   | LONGVARCHAR
        | DATE | TIME    | TIMESTAMP   | BINARY     | VARBINARY | LONGVARBINARY
        | NULL | OTHER   | JAVA_OBJECT | DISTINCT   | STRUCT    | ARRAY
        | BLOB | CLOB    | REF         | BOOLEANINT | BOOLEANCHAR
        | DOUBLE

I can only describe the following fields because I haven't used any of the others:

THINGS NOT IN THIS DOCUMENT

I do not use the torque ID Broker. I haven't gotten it to work yet (when I execute "ant -buildfile build-torque.xml id-table-init-sql" it generates an empty oracle-id-table-init.sql file), so I still use my own ID broker (PrimaryKeyGenerator.java).

DESIRED TORQUE IMPROVEMENTS

Some of these things may already be there. I'm not sure:

PreparedStatements should be standard. I shouldn't need to do a search and replace to force torque to use them for select statements. (My ant target automatically does this replacement everytime I use ant to execute torque, but I'd prefer to set that info in a properties file instead of having to do a source code replace.)

Support for hierarchical objects which optionally load parts on demand instead of loading all data all at once. I have projects where I have a single object that represents multiple tables. Such an object would never load anything from any table until an accessor is used to access a value which comes from a table that hasn't been loaded yet. At that time it loads all the values from a row in that table. This is obviously a complex subject and I don't know if it could be adequately expressed in a schema.xml file, but it might be worth some investigation.

Support for automatic caching of objects in a way that allows them to expire after certain lengths of time or if the user decides, based on other criteria, that a newer version is available in the DB. Torque has some caching stuff (the generated manager classes), but it's apparently still considered to be sort of alpha at this point.

I'd prefer to be able to specify everything in the ant task rather than have a special properties file (in my example it was "gamerprofTorqueBuild.properties"). That way, I can specify everything in the ant script if I want to, or I can create my own properties file and load from it using ant if that floats by boat.

I'd like to be able to specify, in the schema, information that can be used to do runtime verification of values. For instance, I might want to specify minimum and maximum values for integers. It should be possible to turn the verification off at runtime if desired (controllable per-table). It should be possible to prevent any of the verification code from being generated at all (some people might consider it pointless overhead). It should be possible to create verification plugins which could be easily added to torque.