Chapter 4. Including Cayenne in a Project

Table of Contents

Jar Files
Dependencies
Maven Projects
Gradle Projects
Ant Projects

Jar Files

This is an overview of Cayenne jars that is agnostic of the build tool used. The following are the important libraries:

  • cayenne-di-4.1.M1.jar - Cayenne dependency injection (DI) container library. All applications will require this file.

  • cayenne-server-4.1.M1.jar - contains main Cayenne runtime (adapters, DB access classes, etc.). Most applications will require this file.

  • cayenne-client-4.1.M1.jar - a client-side runtime for ROP applications.

  • Other cayenne-* jars - various Cayenne tools extensions.

Dependencies

With modern build tools like Maven and Gradle, you should not worry about tracking dependencies. If you have one of those, you can skip this section and go straight to the Maven section below. However if your environment requires manual dependency resolution (like Ant), the distribution provides all of Cayenne jars plus a minimal set of third-party dependencies to get you started in a default configuration. Check lib and lib/third-party folders for those.

Dependencies for non-standard configurations will need to be figured out by the users on their own. Check pom.xml files of the corresponding Cayenne modules in one of the searchable Maven archives out there to get an idea of those dependencies (e.g. http://search.maven.org).

Maven Projects

If you are using Maven, you won't have to deal with figuring out the dependencies. You can simply include cayenne-server artifact in your POM:

<dependency>
   <groupId>org.apache.cayenne</groupId>
   <artifactId>cayenne-server</artifactId>
   <version>4.1.M1</version>
</dependency>

Additionally Cayenne provides a Maven plugin with a set of goals to perform various project tasks, such as synching generated Java classes with the mapping, described in the following subsection. The full plugin name is org.apache.cayenne.plugins:cayenne-maven-plugin.

cgen

cgen is a cayenne-maven-plugin goal that generates and maintains source (.java) files of persistent objects based on a DataMap. By default, it is bound to the generate-sources phase. If "makePairs" is set to "true" (which is the recommended default), this task will generate a pair of classes (superclass/subclass) for each ObjEntity in the DataMap. Superclasses should not be changed manually, since they are always overwritten. Subclasses are never overwritten and may be later customized by the user. If "makePairs" is set to "false", a single class will be generated for each ObjEntity.

By creating custom templates, you can use cgen to generate other output (such as web pages, reports, specialized code templates) based on DataMap information.

Table 4.1. cgen required parameters

Name Type Description
map File DataMap XML file which serves as a source of metadata for class generation. E.g. ${project.basedir}/src/main/resources/my.map.xml


Table 4.2. cgen optional parameters

Name Type Description
additionalMaps File A directory that contains additional DataMap XML files that may be needed to resolve cross-DataMap relationships for the the main DataMap, for which class generation occurs.
client boolean Whether we are generating classes for the client tier in a Remote Object Persistence application. "False" by default.
destDir File Root destination directory for Java classes (ignoring their package names). The default is "src/main/java".
embeddableTemplate String Location of a custom Velocity template file for Embeddable class generation. If omitted, default template is used.
embeddableSuperTemplate String Location of a custom Velocity template file for Embeddable superclass generation. Ignored unless "makepairs" set to "true". If omitted, default template is used.
encoding String Generated files encoding if different from the default on current platform. Target encoding must be supported by the JVM running the build. Standard encodings supported by Java on all platforms are US-ASCII, ISO-8859-1, UTF-8, UTF-16BE, UTF-16LE, UTF-16. See javadocs for java.nio.charset.Charset for more information.
excludeEntities String A comma-separated list of ObjEntity patterns (expressed as a perl5 regex) to exclude from template generation. By default none of the DataMap entities are excluded.
includeEntities String A comma-separated list of ObjEntity patterns (expressed as a perl5 regex) to include from template generation. By default all DataMap entities are included.
makePairs boolean If "true" (a recommended default), will generate subclass/superclass pairs, with all generated code placed in superclass.
mode String Specifies class generator iteration target. There are three possible values: "entity" (default), "datamap", "all". "entity" performs one generator iteration for each included ObjEntity, applying either standard to custom entity templates. "datamap" performs a single iteration, applying DataMap templates. "All" is a combination of entity and datamap.
overwrite boolean Only has effect when "makePairs" is set to "false". If "overwrite" is "true", will overwrite older versions of generated classes.
superPkg String Java package name of all generated superclasses. If omitted, each superclass will be placed in the subpackage of its subclass called "auto". Doesn't have any effect if either "makepairs" or "usePkgPath" are false (both are true by default).
superTemplate String Location of a custom Velocity template file for ObjEntity superclass generation. Only has effect if "makepairs" set to "true". If omitted, default template is used.
template String Location of a custom Velocity template file for ObjEntity class generation. If omitted, default template is used.
usePkgPath boolean If set to "true" (default), a directory tree will be generated in "destDir" corresponding to the class package structure, if set to "false", classes will be generated in "destDir" ignoring their package.
createPropertyNames boolean If set to "true", will generate String Property names. Default is "false"


Example - a typical class generation scenario, where pairs of classes are generated with default Maven source destination and superclass package:

<plugin>
    <groupId>org.apache.cayenne.plugins</groupId>
    <artifactId>cayenne-maven-plugin</artifactId>
    <version>4.1.M1</version>

    <configuration>
        <map>${project.basedir}/src/main/resources/my.map.xml</map>
    </configuration>

    <executions>
        <execution>
            <goals>
                <goal>cgen</goal>
            </goals>
        </execution>
    </executions>
</plugin>

cdbgen

cdbgen is a cayenne-maven-plugin goal that drops and/or generates tables in a database on Cayenne DataMap. By default, it is bound to the pre-integration-test phase.

Table 4.3. cdbgen required parameters

Name Type Description
map File DataMap XML file which serves as a source of metadata for DB schema generation. E.g. ${project.basedir}/src/main/resources/my.map.xml
dataSource XML An object that contains Data Source parameters


Table 4.4. <dataSource> parameters

Name Type Required Description
driver String Yes A class of JDBC driver to use for the target database.
url String Yes JDBC URL of a target database.
username String No Database user name.
password String No Database user password.


Table 4.5. cdbgen optional parameters

Name Type Description
adapter String Java class name implementing org.apache.cayenne.dba.DbAdapter. While this attribute is optional (a generic JdbcAdapter is used if not set), it is highly recommended to specify correct target adapter.
createFK boolean Indicates whether cdbgen should create foreign key constraints. Default is "true".
createPK boolean Indicates whether cdbgen should create Cayenne-specific auto PK objects. Default is "true".
createTables boolean Indicates whether cdbgen should create new tables. Default is "true".
dropPK boolean Indicates whether cdbgen should drop Cayenne primary key support objects. Default is "false".
dropTables boolean Indicates whether cdbgen should drop the tables before attempting to create new ones. Default is "false".


Example - creating a DB schema on a local HSQLDB database:

<plugin>
    <groupId>org.apache.cayenne.plugins</groupId>
    <artifactId>cayenne-maven-plugin</artifactId>
    <version>4.1.M1</version>
    <executions>
        <execution>
            <configuration>
                <map>${project.basedir}/src/main/resources/my.map.xml</map>
                <adapter>org.apache.cayenne.dba.hsqldb.HSQLDBAdapter</adapter>
                <dataSource>
                    <url>jdbc:hsqldb:hsql://localhost/testdb</url>
                    <driver>org.hsqldb.jdbcDriver</driver>
                    <username>sa</username>
                </dataSource>
            </configuration>
            <goals>
                <goal>cdbgen</goal>
            </goals>
        </execution>
    </executions>
</plugin>

cdbimport

cdbimport is a cayenne-maven-plugin goal that generates a DataMap based on an existing database schema. By default, it is bound to the generate-sources phase. This allows you to generate your DataMap prior to building your project, possibly followed by "cgen" execution to generate the classes. CDBImport plugin described in details in chapter "DB-First Flow"

Table 4.6. cdbimport parameters

Name Type Required Description
map File Yes DataMap XML file which is the destination of the schema import. Can be an existing file. If this file does not exist, it is created when cdbimport is executed. E.g. ${project.basedir}/src/main/resources/my.map.xml. If "overwrite" is true (the default), an existing DataMap will be used as a template for the new imported DataMap, i.e. all its entities will be cleared and recreated, but its common settings, such as default Java package, will be preserved (unless changed explicitly in the plugin configuration).
adapter String No A Java class name implementing org.apache.cayenne.dba.DbAdapter. This attribute is optional. If not specified, AutoAdapter is used, which will attempt to guess the DB type.
dataSource XML Yes An object that contains Data Source parameters
dbimport XML No An object that contains detailed reverse engineering rules about what DB objects should be processed. For full information about this parameter see "DB-First Flow" chapter.


Table 4.7. <dataSource> parameters

Name Type Required Description
driver String Yes A class of JDBC driver to use for the target database.
url String Yes JDBC URL of a target database.
username String No Database user name.
password String No Database user password.


Table 4.8. <dbimport> parameters

Name Type Description
defaultPackage String A Java package that will be set as the imported DataMap default and a package of all the persistent Java classes. This is a required attribute if the "map" itself does not already contain a default package, as otherwise all the persistent classes will be mapped with no package, and will not compile.
forceDataMapCatalog boolean Automatically tagging each DbEntity with the actual DB catalog/schema (default behavior) may sometimes be undesirable. If this is the case then setting forceDataMapCatalog to true will set DbEntity catalog to one in the DataMap. Default value is false.
forceDataMapSchema boolean Automatically tagging each DbEntity with the actual DB catalog/schema (default behavior) may sometimes be undesirable. If this is the case then setting forceDataMapSchema to true will set DbEntity schema to one in the DataMap. Default value is false.
meaningfulPkTables String A comma-separated list of Perl5 patterns that defines which imported tables should have their primary key columns mapped as ObjAttributes. "*" would indicate all tables.
namingStrategy String The naming strategy used for mapping database names to object entity names. Default is org.apache.cayenne.dbsync.naming.DefaultObjectNameGenerator.
skipPrimaryKeyLoading boolean Whether to load primary keys. Default "false".
skipRelationshipsLoading boolean Whether to load relationships. Default "false".
stripFromTableNames String Regex that matches the part of the table name that needs to be stripped off when generating ObjEntity name. Here are some examples:
<!-- Strip prefix -->
<stripFromTableNames>^myt_</stripFromTableNames>

<!-- Strip suffix -->
<stripFromTableNames>_s$</stripFromTableNames>

<!-- Strip multiple occurrences in the middle -->
<stripFromTableNames>_abc</stripFromTableNames>
usePrimitives boolean Whether numeric and boolean data types should be mapped as Java primitives or Java classes. Default is "true", i.e. primitives will be used.
useJava7Types boolean Whether DATE, TIME and TIMESTAMP data types should be mapped as java.util.Date or java.time.* classes. Default is "false", i.e. java.time.* will be used.
filters configuration XML Detailed reverse engineering rules about what DB objects should be processed. For full information about this parameter see "DB-First Flow" chapter. Here is some simple example:
<dbimport>
	<catalog name="test_catalog">
		<schema name="test_schema">
			<includeTable>.*</includeTable>
			<excludeTable>test_table</excludeTable>
		</schema>
	</catalog>

	<includeProcedure pattern=".*"/>
</dbimport>


Example - loading a DB schema from a local HSQLDB database (essentially a reverse operation compared to the cdbgen example above) :

<plugin>
    <groupId>org.apache.cayenne.plugins</groupId>
    <artifactId>cayenne-maven-plugin</artifactId>
    <version>4.1.M1</version>

    <executions>
        <execution>
            <configuration>
                <map>${project.basedir}/src/main/resources/my.map.xml</map>
                <dataSource>
                    <url>jdbc:mysql://127.0.0.1/mydb</url>
                    <driver>com.mysql.jdbc.Driver</driver>
                    <username>sa</username>
                </dataSource>
                <dbimport>
                    <defaultPackage>com.example.cayenne</defaultPackage>
                </dbimport>
            </configuration>
            <goals>
                <goal>cdbimport</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Gradle Projects

To include Cayenne into your Gradle project you have two options:

  • Simply add Cayenne as a dependency:

    compile 'org.apache.cayenne:cayenne-server:4.1.M1'

  • Or you can use Cayenne Gradle plugin

Gradle Plugin

Cayenne Gradle plugin provides several tasks, such as synching generated Java classes with the mapping or synching mapping with the database. Plugin aslo provides cayenne extension that have some useful utility methods. Here is example of how to include Cayenne plugin into your project:

buildscript {
    // add Maven Central repository
    repositories {
        mavenCentral()
    }
    // add Cayenne Gradle Plugin
    dependencies {
        classpath group: 'org.apache.cayenne.plugins', name: 'cayenne-gradle-plugin', version: '4.1.M1'
    }
}

// apply plugin
apply plugin: 'org.apache.cayenne'

// set default DataMap
cayenne.defaultDataMap 'datamap.map.xml'

// add Cayenne dependencies to your project
dependencies {
    // this is a shortcut for 'org.apache.cayenne:cayenne-server:VERSION_OF_PLUGIN'
    compile cayenne.dependency('server')
    compile cayenne.dependency('java8')
}

Warning

Cayenne Gradle plugin is experimental and it's API can change later.

cgen

Cgen task generates Java classes based on your DataMap, it has same configuration parameters as in Maven Plugin version, described in Table 4.1, “cgen required parameters”. If you provided default DataMap via cayenne.defaultDataMap, you can skip cgen configuration as default settings will suffice in common case.

Here is how you can change settings of the default cgen task:

cgen {
    client = false
    mode = 'all'
    overwrite = true
    createPropertiesNames = true
}

And here is example of how to define additional cgen task (e.g. for client classes if you are using ROP):

task clientCgen(type: cayenne.cgen) {
    client = true
}

cdbimport

This task is for creating and synchronizing your Cayenne model from database schema. Full list of parameters are same as in Maven Plugin version, described in Table 4.6, “cdbimport parameters”, with exception that Gradle version will use Groovy instead of XML.

Here is example of configuration for cdbimport task:

cdbimport {
    // map can be skipped if it is defined in cayenne.defaultDataMap
    map 'datamap.map.xml'

    dataSource {
        driver 'com.mysql.cj.jdbc.Driver'
        url 'jdbc:mysql://127.0.0.1:3306/test?useSSL=false'
        username 'root'
        password ''
    }

    dbImport
        // additional settings
        usePrimitives false
        defaultPackage 'org.apache.cayenne.test'

        // DB filter configuration
        catalog 'catalog-1'
        schema 'schema-1'

        catalog {
            name 'catalog-2'

            includeTable 'table0', {
                excludeColumns '_column_'
            }

            includeTables 'table1', 'table2', 'table3'

            includeTable 'table4', {
                includeColumns 'id', 'type', 'data'
            }

            excludeTable '^GENERATED_.*'
        }

        catalog {
            name 'catalog-3'
            schema {
                name 'schema-2'
                includeTable 'test_table'
                includeTable 'test_table2', {
                    excludeColumn '__excluded'
                }
            }
        }

        includeProcedure 'procedure_test_1'

        includeColumns 'id', 'version'

        tableTypes 'TABLE', 'VIEW'
    }
}

cdbgen

Cdbgen task drops and/or generates tables in a database on Cayenne DataMap. Full list of parameters are same as in Maven Plugin version, described in Table 4.3, “cdbgen required parameters”

Here is example of how to configure default cdbgen task:

cdbgen {

    adapter 'org.apache.cayenne.dba.derby.DerbyAdapter'

    dataSource {
        driver 'org.apache.derby.jdbc.EmbeddedDriver'
        url 'jdbc:derby:build/testdb;create=true'
        username 'sa'
        password ''
    }

    dropTables true
    dropPk true

    createTables true
    createPk true
    createFk true
}

Link tasks to Gradle build lifecycle

With gradle you can easily connect Cayenne tasks to default build lifecycle. Here is short example of how to connect defaut cgen and cdbimport tasks with compileJava task:

cgen.dependsOn cdbimport
compileJava.dependsOn cgen

Note

Running cdbimport automatically with build not always a good choice, e.g. in case of complex model that you need to alter in the Cayenne Modeler after import.

Ant Projects

Ant tasks are the same as Maven plugin goals described above, namely "cgen", "cdbgen", "cdbimport". Configuration parameters are also similar (except Maven can guess many defaults that Ant can't). To include Ant tasks in the project, use the following Antlib:

<typedef resource="org/apache/cayenne/tools/antlib.xml"> 
   <classpath>
   		<fileset dir="lib" >
			<include name="cayenne-ant-*.jar" />
			<include name="cayenne-cgen-*.jar" />
			<include name="cayenne-dbsync-*.jar" />
			<include name="cayenne-di-*.jar" />
			<include name="cayenne-project-*.jar" />
			<include name="cayenne-server-*.jar" />
			<include name="commons-collections-*.jar" />
			<include name="commons-lang-*.jar" />
			<include name="slf4j-api-*.jar" />
			<include name="velocity-*.jar" />
			<include name="vpp-2.2.1.jar" />
		</fileset>
   </classpath> 
</typedef>

cgen

cdbgen

cdbimport

This is an Ant counterpart of "cdbimport" goal of cayenne-maven-plugin described above. It has exactly the same properties. Here is a usage example:

 <cdbimport map="${context.dir}/WEB-INF/my.map.xml"
    driver="com.mysql.jdbc.Driver" 
    url="jdbc:mysql://127.0.0.1/mydb" 
    username="sa"
    defaultPackage="com.example.cayenne"/>