Return-Path:
- Torque is a persistence layer. Torque includes a
- generator to generate all the database
- resources required by your application and includes a runtime
- environment to run the generated classes.
+ The Torque runtime is the only part of Torque you need after you
+ have generated the persistence classes using the Torque Maven plugin
+ resp. the Torque generator. It contains the classes the generated
+ classes depend on.
- Torque was developed as part of the
- Turbine Framework.
- It is now decoupled and can be used by itself. Starting with version
- 2.2 Turbine uses the decoupled Torque.
+ This section contains information about how to work with the generated
+ classes. For information of how to generate these classes, see the
+ Maven plugin reference
+ or the
+ generator reference.
- Torque's runtime environment includes everything you need to use the
- generated OM/Peer classes. It includes a jdbc connection pool.
-
- If your RDBMS is not listed here, please read the document about
- writing DB Adapters
-
- If there is no tester for your RDBMS and you want to help, please read
- the developer-guide, run the tests
- and send your results (and bugfixes ;) to the
- torque-dev@db.apache.org
- list.
-
- Creating beans from Torque objects creates a bridge between
- an environment which knows Torque and has access to a database,
- and another environment which dies not know anything about Torque
- and databases.
-
- For example, you might have a server using Torque, and a java client
- without database access where you want to use data supplied by
- Torque, but do not want to include Torque in any way.
-
- If this is the case, you can create simple beans from Torque objects
- in the server, send them over the network to your client,
- manipulate them there, send them back over the network,
- create Torque objects from the beans,
- and save the objects generated from the beans.
-
- Bean creation is turned off by default. To enable bean creation,
- you have to add the following line to your build.properties file
- in the generator
+ Bean creation is turned off by default. To enable bean creation,
+ you have to generate your object model with the property
+
- Then you just need to regenerate your object model to obtain an object model
- with bean creation support enabled.
+ Creating beans from Torque objects creates a bridge between
+ an environment which knows Torque and has access to a database,
+ and another environment which does not know anything about Torque
+ and databases.
- If bean creation is turned on, the beans are automatically created by torque
- in the bean subpackage of your target package. E.g. in the bookstore example
- in the tutorial, the classes are generated in the com.kazmier.om package,
- so the beans will generated in the package com.kazmier.om.bean.
- Each bean has getters and setters for all the properties defined
- in the schema.xml.
+ For example, you might have a server using Torque, and a java client
+ without database access where you want to use data supplied by
+ Torque, but do not want to include Torque in any way.
- Also, getters and setters for two boolean values, namely
- isNew(), setNew(), isModified() and setModified() are generated, which keep
- track of which changes have already made it into the
- database. You should not normally need to use these.
+ If this is the case, you can create simple beans from Torque objects
+ in the server, send them over the network to your client,
+ manipulate them there, send them back over the network,
+ create Torque objects from the beans,
+ and save the objects generated from the beans.
- If bean creation is enabled, every Torque object gets some
- additional methods. E.g, the author class from the bookstore example
- in the tutorial gets the additional methods
-
- These methods are used to create a bookBean from a book or vice versa.
-
+ If bean creation is turned on, the beans are automatically created
+ by torque in the bean subpackage of your target package.
+ E.g. in the bookstore example in the tutorial, the classes
+ are generated in the com.kazmier.om package, so the beans
+ will be generated in the package com.kazmier.om.bean.
+ Each bean has getters and setters for all the properties defined
+ in the schema.xml.
+
+ Also, getters and setters for two boolean values, namely
+ isNew(), setNew(), isModified() and setModified() are generated,
+ which keep track of which changes have already made it into the
+ database. You should not normally need to use these.
+
+ If bean creation is enabled, every Torque object gets some
+ additional methods. E.g, the author class from the bookstore example
+ in the tutorial gets the additional methods
+
- If a bean is created from an object, the beans gets knowledge about
- whether the object it was created from already exists in the database,
- or whether it was changed after redaing it from the database
- (that is what the isNew() and isModified() methods are for).
- So assuming we have at least one author stored in the database,
- the following code works as expected
-
+ These methods are used to create an AuthorBean from an Author
+ or vice versa.
+
+ If a bean is created from an object, the beans gets knowledge about
+ whether the object it was created from already exists in the database,
+ or whether it was changed after redaing it from the database
+ (that is what the isNew() and isModified() methods are for).
+ So assuming we have at least one author stored in the database,
+ the following code works as expected
+
+ This reads an author from the database,
+ creates a bean from the author,
+ manipulates the bean,
+ and saves the manipulated data back into the database.
+
+ The bean creation process preserves object relations.
+ Consider again the bookstore example from the tutorial:
+ Each book has an author, and an author can have serveral books.
+ So if you have created an author-book relation, e.g. by
+
- The bean creation process preserves object relations.
- Consider again the bookstore example from the tutorial:
- Each book has an author, and an author can have serveral books.
- So if you have created an author-book relation, e.g. by
-
- then the related bookBean is automatically created,
- and can be retrieved by
-
- This is also true in the reverse direction. If you create an
- author from this authorBean, the corresponding book can also
- be retrieved:
-
+ then the related bookBean is automatically created,
+ and can be retrieved by
+
+ This is also true in the reverse direction. If you create an
+ author from this authorBean, the corresponding book can also
+ be retrieved:
+
- Note that only newly created or cached related objects are cosnidered
- in bean creation.
- To elaborate that, consider the case where one author which is related
- to several books is stored in the database.
-
- The following code will NOT transfer the related books into the bean:
-
+ Note that only newly created or cached related objects are considered
+ in bean creation.
+ To elaborate that, consider the case where one author which is related
+ to several books is stored in the database.
+
+ The following code will NOT transfer the related books into the bean:
+
- This is because the related books are never read from the database,
- and thus are not included in bean conversion. To include the
- related books into the author bean, you have to assure that the
- related books are read into memory. This can be done as follows:
-
+ This is because the related books are never read from the database,
+ and thus are not included in bean conversion. To include the
+ related books into the author bean, you have to assure that the
+ related books are read into memory. This can be done as follows:
+
+ Much of the power of Torque stems from the fact that you can easily add to
+ and change the behaviour of the generated Peer and Data Object classes
+ by adding or overriding methods. To keep your changes apart from the
+ autogenerated code, Torque provides two Peer classes and two
+ Data Object classes per table: The Base<table-name>Peer and
+ Base<table-name> classes are overwritten each time you regenerate
+ the classes from the schema and contain all functionality provided by
+ Torque.
+ The <table-name>Peer and <table-name> 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 <table-name>Peer and
+ <table-name> classes.
+
+ 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:
+
+
-Torque can use any connection pool implementing the
-Torque provides factories to use the commons-dbcp as well as a general
-factory that uses jndi to retrieve the
-Before going over how to configure the factories, which will take up most the
-content of this document, you must first consider your database handles and
-adapters.
-
-A database handle is the name attribute that was used in the
-
-In all examples that follow we will use the handle 'bookstore'. As Torque has
-the ability to use multiple databases you can tell it which one to use by
-default thus:
+ Torque is initialized by calling one of the
+ When calling one of the
+ Upon initialisation, also the runtime model of the database,
+ i.e. the
+ A database handle is the name attribute that was used in the
+
+ In all examples that follow we will use the handle 'bookstore'.
+ As Torque has the ability to use multiple databases you can tell it
+ which one to use by default thus:
+
-Previously, Torque provided an internal map between many Drivers and a set
-of adapter classes which are used to account for differences among databases.
-This arrangement is no longer possible using
+ Previously, Torque provided an internal map between many Drivers
+ and a set of adapter classes which are used to account for
+ differences among databases.
+ This arrangement is no longer possible using
-The valid values are:
-
-This factory uses the more full featured DataSource available in the
-commons-dbcp package. SharedPoolDataSourceFactory provides an easy way
-to configure this pool and it assumes you will have a jdbc Driver class
-providing the physical database connections. Again, you must let torque know
-you are using this factory.
-
+ The valid values are:
+
+ Torque can use any connection pool implementing the interface
+
+ Torque provides factories to use the commons-dbcp pools as well as a
+ general factory that uses jndi to retrieve the
+ This factory uses the SharedDataSource available in the
+ commons-dbcp package. SharedPoolDataSourceFactory provides an easy way
+ to configure this pool and it assumes you will have a jdbc Driver class
+ providing the physical database connections. Again, you must let
+ Torque know you are using this factory:
+
-Then there are two sets of properties related to the pool configuration and
-settings for making the connection to the database.
-
+ Then there are two sets of properties related to the pool
+ configuration and settings for making the connection to the database.
+ The "connection" set contains all information to create a
+ physical connection to the database:
+
-Comparing this with the torque's old pool, you can see that this pool does not
-rely on expirying connections periodically to maintain their validity. The
-pool can be setup to test each connection before returning it to the
-application, so the likelihood of the application receiving a bad connection
-is much smaller than using
-This factory is used if the
+ The "pool" set contains information of how the pool should
+ handle the physical connections. See
+ the dbcp reference
+ for possible properties. For example, you could use:
+
+ Torque also includes a factory for the
+
+ This factory is used if the
-If a pool is known to already be available via jndi, only one more property
-is required.
-
+ In this section, it is assumed that a
+ If a pool is known to already be available via jndi,
+ only one more property is required for Torque:
+
-This line defines the string that will be used to lookup the
-
-Such environment settings will likely not be necessary when running within
-a J2EE container, but they are useful in other cases. One such case is when
-running torque's unit/run-time tests
-
-One of the advantages of jndi is that it supports changing
-the
+ This line defines the string that will be used to lookup the
+
+ Such environment settings will most likely not be necessary when running
+ within a J2EE container, but they are useful in other cases.
+
+ One of the advantages of jndi is that it supports changing
+ the
-This property is optional. If not specified, it defaults to 0 (no caching).
-
-Generally a J2EE environment such as a servlet engine or application server is
-expected to provide a jdbc2 compatible connection pool. If your application
-is not running within such an environment, or even if it is and torque is your
-only use of a connection pool, torque provides a simple properties file
-method of configuring a
-In the above example two objects are being configured. One is a
- Torque uses the jndi path properties to know where to deploy the
-configured objects. So you would have the two following properties in
-addition to the datasource props:
-
+ This property is optional. If not specified, it defaults to 0
+ (no caching).
+
+ Generally a J2EE environment such as a servlet engine or application
+ server is expected to provide a jdbc2 compatible connection pool.
+ If your application is not running within such an environment,
+ or even if it is and torque is your only use of a connection pool,
+ Torque provides a simple properties file method of configuring a
+
+ Too use this feature, you need to specify the jndi configuration
+ parameters as shown above, setting the factory and the jndi path.
+ In addition to that, you need to configure
+ the
+ plus the properties for the factory and the jndi path:
+
-The second handle, DBbookstore, has no relevance to torque, other than
-to uniquely identify this group of properties as belonging together. Any
-unique handle may be used.
-
-If you have other parts of your application that need to use the same
-connection pool and torque cannot be guaranteed to be initialized in time for
-these other uses, or if you just want to follow your j2ee environment's
-standard jndi deployment pattern, torque can just make use of these externally
-deployed pools. Here is an example using catalina of deploying the pool that
-used to come with torque, but is now part of commons-jdbc2pool.
- In server.xml, the following would be added to the <Context> for your
-webapp:
- In web.xml. Elements must be given in the order of the dtd described in
-the servlet specification:
-
-Catalina deploys all objects configured similarly to above within the
-java:comp/env namespace so the jndi path given in
-Torque.properties would be
-
-Remember that jdbc2 pools expect a
-
-Catalina provides a default
-The following example shows a complete torque configuration from
-scarab, an issue tracking application, running under catalina, but using torque
-to deploy the
-
-
-
-
- RDBMS
- Driver
- Status
- Tester
-
-
- Axion
- org.axiondb.jdbc.AxionDriver
- Alpha
-
-
-
- Cloudscape
- COM.cloudscape.core.JDBCDriver
-
-
-
-
- DB2
- COM.ibm.db2.jdbc.{app|net}.DB2Driver
-
-
-
-
- DB2/AS400
- com.ibm.as400.access.AS400JDBCDriver
- Possible case-insensitivity issues
- Scott Weaver
-
-
- Derby
- org.apache.derby.jdbc.EmbeddedDriver
- Only the embedded driver works.
- Thomas Fischer
-
-
- Firebird
- org.firebirdsql.jdbc.FBDriver
- idMethod="native" does not work
- Thomas Fischer
-
-
- Hypersonic
- org.hsql.jdbcDriver
-
-
-
-
- Informix
- com.informix.jdbc.IfxDriver
-
-
-
-
- InstantDB
- org.enhydra.instantdb.jdbc.idbDriver
-
-
-
-
- Interbase
- interbase.interclient.Driver
-
-
-
-
- MS Access
- sun.jdbc.odbc.JdbcOdbcDriver
-
-
-
-
- MS SQL
- com.microsoft.jdbc.sqlserver.SQLServerDriver
-
-
-
-
- MySQL
- org.gjt.mm.mysql.Driver
- No known problems
- Scott Eade
-
-
- Oracle
- oracle.jdbc.driver.OracleDriver
- Issues with LOBs
-
-
-
- Postgres
- org.postgresql.Driver
- No known problems
- Scott Eade
-
-
- SapDB
- com.sap.dbtech.jdbc.DriverSapDB
-
-
-
-
- Sybase
- com.sybase.jdbc2.jdbc.SybDriver
-
- JDBCToXMLSchema task will not generate the schema properly.
- All other tests pass.
-
- Jeffrey D. Brekke
-
-
- Weblogic
- weblogic.jdbc.pool.Driver
-
-
- torque.generateBeans
code> set to true
.
+ Initialisation and Configuration
+
+ Reading from the database
+
+ Writing to the database
+
+ Extending the base classes
+
+ Managers and Caching
+
+ Beans
+
+ Relevant classes
+
+ Supporting a new Database
+
+ DataSource
.
-Torque expects a factory that can return a DataSource
and can
-be configured using torque's configuration file.
-DataSource
.
-The jndi factory looks up a DataSource
bound to jndi; it
-also provides a simple property file based way to configure and deploy most
-DataSource
's, though in many cases a pool may already be
-bound to jndi and torque only needs to use it.
-<database>
tag of the schema.xml file. If the name
-attribute is not used, then the handle would be 'default'.
-Torque.init()
+ methods. Torque must be initialized before it is used, and it must not
+ be initialized more than once.
+ Torque.init()
methods, you
+ must supply either the path to a configuration file or the configuration
+ itself. The configuration must contain a valid DataSource
,
+ a default database handle, and an adapter for each
+ DataSource
.
+ For details, see the section Configuration
+ below.
+ DatabaseMaps
, are built by autogenerated
+ MapBuilder
classes. This happens automatically,
+ so usually you need not bother about it.
+ The detailed procedure is the following: Each peer class registers
+ its Map builder with the Torque runtime when the Base Peer Class is loaded
+ (Usually, a peer class is loaded if one of the constants
+ for a column name is accessed, or a method is called).
+ If Torque is already initialized when the Peer class is loaded
+ (this is usually the case) the Map Builder builds the database map
+ instantly and makes it avaliable to Torque. If Torque is not yet
+ initialized, the Peer class stores the Map Builder with Torque,
+ which builds the database Map when Torque is initialized.
+ <database>
tag of the schema.xml file. If the name
+ attribute is not used, then the handle would be 'default'.
+ DataSource
, so
-the adapter must be given in the configuration.
-The adapter property is given as:
-DataSource
,
+ so the adapter must be given in the configuration.
+ The adapter property is given as:
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DataSource
. Torque expects a factory that can return a
+ DataSource
and can be configured using Torque's
+ configuration file.
+ DataSource
.
+ The jndi factory looks up a DataSource
bound to jndi; it
+ also provides a simple property file based way to configure and deploy most
+ DataSource
's, though in many cases a pool may already be
+ bound to jndi and torque only needs to use it.
+ TorqueClassicDataSource
.
-Torque also includes a factory for the PerUserPoolDataSource
.
-Please see the commons-dbcp javadoc for more info.
-DataSource
is to be available via
-jndi. It is possible to use this factory to deploy a DataSource
-into jndi, but in many cases for using this factory the DataSource
-is already deployed. This factory is specified with the following property:
-PerUserPoolDataSource
.
+ Please see the commons-dbcp javadoc for more info.
+ DataSource
is to be available
+ via jndi. It is possible to use this factory to deploy a
+ DataSource
into jndi, but in many cases for using this
+ factory the DataSource
is already deployed.
+ This factory is specified with the following property:
+ DataSource
+ is available via jndi. Usually, a J2EE environment can be configured
+ to bind a DataSource
into jndi for further use.
+ For example, Tomcat can bind a DataSource
into jndi, see
+ the Tomcat Documentation
+ for details.
+ DataSource
within the default jndi InitialContext
.
-If everything is configured and the default InitialContext
-contains the DataSource
, this is all that is
-needed. The default InitialContext
is chosen according to the
-rules given in the class's javadoc. If the default has not been configured,
-you can specify any other environment properties that are needed to instantiate
-the InitialContext
as extra properties of the form,
-torque.jndi.<handle>.<env-var>. A couple examples are shown below:
-DataSource
on the fly. On the other hand this means that the
-actual DataSource
object must be looked up in the context with
-every database operation. To avoid this, the factory provides a simple
-caching mechanism, which stores the DataSource
object for a
-configurable amount of time (im ms). The time between two
-lookups is specified as follows:
-DataSource
within the default jndi
+ InitialContext
.
+ If everything is configured and the default InitialContext
+ contains the DataSource
, this is all that is
+ needed. The default InitialContext
is chosen
+ according to the rules given in the class's javadoc.
+ If the default has not been configured, you can specify any other
+ environment properties that are needed to instantiate
+ the InitialContext
as extra properties of the form,
+ torque.jndi.<handle>.<env-var>.
+ A couple of examples are shown below:
+ DataSource
on the fly.
+ On the other hand this means that the actual DataSource
+ object must be looked up in the context with every database operation.
+ To avoid this, the factory provides a simple caching mechanism,
+ which stores the DataSource
object for a configurable
+ amount of time (im ms). The time between two
+ lookups is specified as follows:
+ DataSource
and deploying it via jndi.
-The one property that is necessary for all DataSource
's is the
-classname the DataSource
implementation. Beyond that the properties are implementation specific.
-DataSource
's contain getters/setters for configuration. You
-can specify the values for these properties as shown below:
-DataSource
that is used by the application (torque). The other is
-a ConnectionPoolDataSource
that is provided as part of a jdbc2
-driver. If the jdbc driver implementation you are using does not fully
-implement the jdbc2 specification. commons-dbcp provides an
-adapter for older Driver
based drivers. Another alternative is
-provided in commons-dbcp where BasicDataSource
provides a
-DataSource
frontend, and has properties to directly configure
-a jdbc1 Driver
. But regardless of the implementation torque
-uses commons-beanutils package to call the setters on the object using
-reflection.
-DataSource
and deploying it via jndi.
+ DataSource
which should be bound into jndi.
+ The one property that is necessary for all DataSource
's
+ is the classname of the DataSource
implementation.
+ Beyond that the properties are implementation specific, depending on the
+ DataSource
's setters for the configuration.
+ You can specify the values for the setters as properties in the
+ configuration file. For example, dbcp's BasicDataSource
+ could be configured as shown below:
+ ConnectionPoolDataSource
-available via jndi under the name given in the dataSourceName, so you will
-need entries in server.xml and web.xml for this object as well.
-DataSource
that can be used as well
-and it is configured similarly, but detailed information on that
-implementation is here. Note that the
-"type attribute/ref-type element" value of "javax.sql.DataSource" appears to
-be reserved for catalina's default implementation, which is why the
-implementation classname is used in our configuration example.
-DataSource
. It is here to
-put together some of the details shown above.
-
+ In this section, the bits explained above are assembled to full + examples of configuration files for the Torque runtime. Do not forget + to change the values to match your database environment. +
+ ++ Using SharedPoolDataSourceFactory (this example is also used in the + Tutorial): +
+ +
+ Using JndiDataSourceFactory with externally bound
+ DataSource
:
+
+ Using JndiDataSourceFactory to bind a DataSource
to jndi:
+
- Note: Managers and the caching they provide is fairly new (as this is - written on 2002-04-11). Feedback is welcome and usage by the brave - is encouraged. But the api should not be expected to be stable. -
-- A manager is responsible for instantiating new objects, retrieving stored - objects, and possibly caching these objects. Managers provide static - accessors for much of its functionality, so usage examples are: -
- -- If no-arg constructor of FooManager, - calls setRegion(region) where the String region is the key used to - determine the cache, the manager will cache instances of Foo retrieved - via the getInstance(ObjectKey id) and getInstances(List ids) methods. - One possibility for the region key is the - fully qualified classname with dots replaced by underscores. -
- -
+ To use Managers in Torque, you need to generate your object model
+ with the generator option torque.useManagers = true
.
+
+ A manager is responsible for instantiating new objects, retrieving stored + objects, and possibly caching these objects. Managers provide static + accessors for much of its functionality, so usage examples are: +
+ ++ Note: Managers and the caching they provide is fairly new. Feedback + is welcome and usage by the brave is encouraged. + But the api should not be expected to be stable. +
+ +
+ Also, note that the cache is global and is not Transaction-aware.
+ This implies that isolation of different transactions will be difficult
+ to achieve. For example, you might read uncommited data out of the
+ cache even if you database transaction isolation is set to
+ READ_COMMITTED
.
+
+ If no-arg constructor of FooManager, + calls setRegion(region) where the String region is the key used to + determine the cache, the manager will cache instances of Foo retrieved + via the getInstance(ObjectKey id) and getInstances(List ids) methods. + One possibility for the region key is the + fully qualified classname with dots replaced by underscores. +
+ +- The key given for the region is used in a JCS - configuration file, cache.ccf, to set up a cache that the manager uses - to store objects for which it is responsible. See the JCS - - documentation for details on configuring JCS. But here is a - simple section that creates an in-memory only LRU cache for FooManager. -
++ The key given for the region is used in a JCS + configuration file, cache.ccf, to set up a cache that the manager uses + to store objects for which it is responsible. See the JCS + + documentation for details on configuring JCS. But here is a + simple section that creates an in-memory only LRU cache for FooManager. +
-- It is a good idea to set a region for each manager, but this behavior - is optional. There also will be no caching if JCS is - not configured for the region given in the Constructor. -
- -- The generated object model classes have methods for getting objects - that are related by foreign keys. If the FOO table contains an fk to - the BAR table then Foo.getBar() will exist. This method uses - BarManager.getInstance(bar_id) and therefore will return a cached - Bar, if the Bar has been previously requested (and it still exists in - the cache.) -
- -- The above fk relationship will also generate a Bar.getFoos(Criteria). It - would be preferrable that repeated requests to this method returned - cached results as opposed to hitting the db for each call. It could be - possible to add such caching to the generated method, and Criteria - implements an equals() method that would make this possible. But - determining the equality of a Criteria is complex and possibly buggy (this - is the perception of the author of this doc, there are no known bugs). - Invalidating the results has also not been reduced to templated Java code. - So whether to cache these kinds of results is left to the developer - who is using torque. -
- -- It is a good practice to write methods within Bar that wrap the - getFoos(Criteria) method. The conversion from application parameters - to a Criteria is then implemented in a more maintainable manner. For - example: -
++ It is a good idea to set a region for each manager, but this behavior + is optional. There also will be no caching if JCS is + not configured for the region given in the Constructor. +
+ ++ The generated object model classes have methods for getting objects + that are related by foreign keys. If the FOO table contains an fk to + the BAR table then Foo.getBar() will exist. This method uses + BarManager.getInstance(bar_id) and therefore will return a cached + Bar, if the Bar has been previously requested (and it still exists in + the cache.) +
+ ++ The above fk relationship will also generate a Bar.getFoos(Criteria). It + would be preferrable that repeated requests to this method returned + cached results as opposed to hitting the db for each call. It could be + possible to add such caching to the generated method, and Criteria + implements an equals() method that would make this possible. But + determining the equality of a Criteria is complex and possibly buggy (this + is the perception of the author of this doc, there are no known bugs). + Invalidating the results has also not been reduced to templated Java code. + So whether to cache these kinds of results is left to the developer + who is using torque. +
+ ++ It is a good practice to write methods within Bar that wrap the + getFoos(Criteria) method. The conversion from application parameters + to a Criteria is then implemented in a more maintainable manner. For + example: +
-- In the above code the database will be hit for every call to the method. - BarManager provides some convenience code to add caching to the above - method, so it can be rewritten as: -
++ In the above code the database will be hit for every call to the method. + BarManager provides some convenience code to add caching to the above + method, so it can be rewritten as: +
-- The getMethodResult() method returns a MethodResultCache object, which - creates a key from the arguments given in the get method. All the - arguments must be Serializable. The first object should be the business - object on which the method was called. If the object is not Serializable - or the method is static, a String as given by Object.toString() method or - the className might be used. The second argument is the method name. - There are versions of the get method that take up to 3 additional arguments - that will be the arguments to the method, or if they are not Serializable - some Serializable proxy. There is also a get method that takes an - Object[] that can be used for methods that have more than 3 arguments; the - first two objects in the array should be the instance and method name. - The reason for not just having the Object[] format is that keys are pooled - and since most methods will be less than 4 arguments, object creation - related to the cache is minimized. Now the method will return cached - results as long as the results remain in the cache. So there must be some - way to invalidate these results, if the database changes in a way that - is likely to affect the result that should be returned by the method. -
- -- An event model exists for invalidating cached method results. Continuing - the example from above, BarManager should register itself as a listener - with the FooManager. - Then FooManager will notify BarManager, if a foo.save() is called - that might affect its cached results. The following code is added to - BarManager.java which implements the CacheListener interface. -
- -+ An event model exists for invalidating cached method results. Continuing + the example from above, BarManager should register itself as a listener + with the FooManager. + Then FooManager will notify BarManager, if a foo.save() is called + that might affect its cached results. The following code is added to + BarManager.java which implements the CacheListener interface. +
+ +- When a foo which is of interest to BarManager is saved, the instance is - passed - to the appropriate listener method. This object may contain information - that could result in no action or possibly more precise repair of the - cached data. In the above examples the cache is just cleared of all - data that is potentially invalid. - Some code is also added to FooManager to support the invalidation. -
- -+ When a foo which is of interest to BarManager is saved, the instance is + passed to the appropriate listener method. This object may contain + information that could result in no action or possibly more precise + repair of the cached data. In the above examples the cache is just + cleared of all data that is potentially invalid. + Some code is also added to FooManager to support the invalidation. +
+ +- Now FooManager will notify BarManager when foo's are modified. -
++ Now FooManager will notify BarManager when foo's are modified. +
-
-A database adapter class is a class that extends
-org.apache.torque.adapter.DB
and encapsulates access to a specific
-RDBMS implementation. Database adapter classes already found in Torque include
-DBOracle, DBMM, DBSybase, etc. These classes allow Torque to gain access to a
-wide range of databases in a uniform manner. This allows you to easily swap
-between databases without any modification to Torque or the application built
-on top of Torque.
-
-Why is this necessary if Java already offers uniform database access -in the form of JDBC? Unfortunately, underlying databases still -use different SQL implementations and conventions. For example, the use -of single and double quotes varies. The use of database adapter classes in -Torque endeavors to overcome this problem. -
- --To add a new database adapter class to Torque you must follow these -steps: -
- --
org.apache.torque.adapter.DB
(where dbname is the name of
- the database or database driver you wish to add to Torque). DB is an
- abstract class, so you need to implement a number of methods.-If you are adding support for a new RDBMS, then you will probably also -need to create a set of Velocity templates--used by Torque to generate -a SQL schema for your RDBMS--in the directory -conf/torque/templates/sql/base/<dbname>. The recommend method for -doing this is to copy an existing set of templates and adapt them to -your RDBMS as needed. -
++ In the Torque Runtime, all information about a specific Database is + gathered in a so-called Database adapter class. So if you want to + support a new database in the runtime, you need to provide a + Database Adapter class for this database. +
+ ++ If you are adding support for a new RDBMS, then you will probably also + want to support the database in the Torque generator. + To do this, you need to create a set of Velocity templates--used + by Torque to generate a SQL schema for your RDBMS--in the templates + component. The recommend method for doing this is to copy an existing set + of templates and adapt them to your RDBMS as needed. This is not + elaborated forther here. +
+ +
+ A database adapter class is a class that extends
+ org.apache.torque.adapter.DB
and encapsulates access
+ to a specific RDBMS implementation. Database adapter classes already
+ found in Torque include DBOracle, DBMM, DBSybase, etc.
+ These classes allow Torque to gain access to a wide range of databases
+ in a uniform manner. This allows you to easily swap between databases
+ without any modification to Torque or the application built
+ on top of Torque.
+
+ Why is this necessary if Java already offers uniform database access + in the form of JDBC? Unfortunately, underlying databases still + use different SQL implementations and conventions. For example, the use + of single and double quotes varies. The use of database adapter classes in + Torque endeavors to overcome this problem. +
+ ++ To add a new database adapter class to Torque you must follow these + steps: +
+ ++
org.apache.torque.adapter.DB
(where dbname is the name of
+ the database or database driver you wish to add to Torque). DB is an
+ abstract class, so you need to implement a number of methods.
+ org.apache.torque.adapter.IDMethod.AUTO_INCREMENT
,
+ org.apache.torque.adapter.IDMethod.SEQUENCE
, and
+ org.apache.torque.adapter.IDMethod.NO_ID_METHOD
.
+ obj
is the name of the sequence.
+ Databases that use auto increment fields should return the last
+ generated id; obj
is the name of the table in this case.
+ Databases that do not support this must return null.
+