![]() |
![]() |
Back to the Speedo documentation
The .jdo files describe which classes are the persistent. In the current version of Speedo,the user is required to specify which are the persistent fields for each class. For each class and each field, the user can specify (optionally) extensions for Speedo. Extensions allow the user to choose a mapping of the persistent object into a relational database.
An extension named 'sql-name' permits the user to specify the table name where the persistent class is stored.
<class name="A">
<extension vendor-name="speedo" key="sql-name" value="TABLE_A"/>
</class>
If this extension is not specified, by default the table name is
equal to the name of the class (whithout the package name).
Speedo supports 4 types of identifiers:
<class name="A" identity-type="datastore">
...
</class>
<class name="A" identity-type="datastore">
<extension vendor-name="speedo" key="id" value="sequence"/>
</class>
<class name="A" identity-type="datastore">
<extension vendor-name="speedo" key="sql-seq-name" value="SEQ_TABLE_A"/>
</class>
Identifier allocator:The user can specify a class implementing the interface 'org.objectweb.jorm.facilty.naming.rdb.SequenceIdAllocator'. containing only the long allocateId(long seqValue, Object key) method. To specify the use of an identifier allocator, you have to put the class name as value associated to the key 'sql-seq-allocator'.
Even if the identifier is allocated by a sequence you can want to have access to the identifier field. You can declare a persistent field as primary which the type is long of java.lang.Long. If you choose 'long' the null references are stored with the -1 value. If you choose 'java.lang.long' the null references are with the NULL SQL value.
<class name="Invoice" identity-type="application
identity-type="application"">
<field name="number" primary-key="true"/>
</class>
<class name="Address" identity-type="application
identity-type="application"
objectid-class="invoice.AddressID">
<field name="name" primary-key="true"/>
<field name="street" primary-key="true"/>
<field name="town" primary-key="true"/>
</class>
class AddressID {
public String name;
public String street;
public String town;
...
}
<class name="A" identity-type="datastore">
<extension vendor-name="speedo" key="id" value="polymorph2l"/>
</class>
All the extension concerning the identifier must be done on the class tag in the .jdo files.
An extension named 'sql-name' permits to specify the name of the column in the table where the persistent class is stored.
<field name="f1">
<extension vendor-name="speedo" key="sql-name" value="F1_COL"/>
</field>
If this extension is not specified, by default the column name
is equal to the name of the field.
An extension named 'sql-type' permits to specify the type of the column in table name where the persistent class is stored.
<field name="f1">
<extension vendor-name="speedo" key="sql-type" value="VARCHAR(26)"/>
</field>
If this extension is not specified, by default the column type
depends on the field type and the used data base.
An extension named 'size' permits to specify the size of primitive field. It permits to define the size of SQL Type.
<field name="f1">
<extension vendor-name="speedo" key="size" value="12"/>
</field>
This property is used for String, BigDecimal or BigInteger
fields. For BigXXX fields, this property represents the number of
digits (integer + decimal). For String fields, this property represents
the maximal String length.
This property is ignored if the sql-type property is specified.
An extension named 'scale' permits to specify the size of primitive field. This value is interesting for a String field. It permits to choose the size of the table column.
<field name="f1">
<extension vendor-name="speedo" key="scale" value="12"/>
</field>
This property is used for BigDecimal fields and it represents
the number of digits at dot right.
This property is ignored if the sql-type property is specified.
An extension named 'field-converter' permits to change the usual translation between the memory type and the data support type for a primitive field. For example, if the user has a legacy relationnal database, it can map an integer field into a String (VARCHAR on a RDB). To do this, the user must implement the org.objectweb.speedo.api.UserFieldMapping interface provided by Speedo. This implementation is able to convert a memory value to a data store value and reversly. Finally, the user must indicate, as value of the extenstion 'field-converter', the class name of the interface implementation.
<field name="f1">And here is the source code of the String2intConverter class
<extension vendor-name="speedo" key="field-converter"
value="com.foo.bar.String2intConverter"/>
</field>
package com.foo.bar;
public class String2intConverter implements UserFieldMapping {
public Class getStorageType() {
return String.class;
}
public Class getMemoryType() {
return Integer.TYPE;
}
public Object toMemory(Object storagevalue) {
return Integer.valueOf((String) storagevalue)
}
public Object toStorage(Object memoryvalue) {
return (memoryvalue == null ? null : memoryvalue.toString());
}
}
class A {
private B myB;
...
}
class B {
...
}
A reference field is a field which references a Persistent class and not a multivalued reference (Collection/Set/...). Speedo allows the user to specify which primary key is referenced and therefore where is the foreign key. For a simple reference there are two solutions:
![]() ![]() |
<field name="refToB"> |
This is a foreign key on the primary key of the targeted persistent class (B).
![]() ![]() |
<field name="refToB"> |
This is a foreign key on the primary key of the source persistent class (A).
For more information about the values corresponding to the key
"source-foreign-keys" and "target-foreign-keys", see the section foreign keys declaraction
A "collection" field is a field which references several Persistent classes. Speedo supports several types of structure (java.util.Collection, java.util.Set, java.util.List, []...). Depending of the type of relation (One-Many, Many-Many), a join table can be specified. The join table is optional for a One-Many relation; a foreign key can indeed be defined in the table of the referenced persistent class. On the opposite, a join table is required for a Many-Many relation. The following examples go through the supported cases:
class A {
private Collection myBs;
}
class B {
}
The user does not specify any information about the mapping. By default the relation is stored into a join table. The table and the columns names are chosen by Speedo.
![]() ![]() |
<field name="collectionOfB" persistence-modifier="persistent"> |
class A {
private Collection myBs;
}
class B {
private A myA;
}
The relation is One-Many and there is no join table. The "source-foreign-keys" extension defines the name of the foreign key column in the table of the referenced persistent class.
![]() ![]() |
<class name="A"> |
class A {
private Collection myBs;
}
class B {
}
The relation is Many (no reverse field exists) and there is a join table. The key "join-table" defines the name of the join table. If it is not specified, the default table name is defined as the concatenation of the short class name (without the package name) of the source class with the name of the collection field. The "source-foreign-keys" and "target-foreign-keys" extensions define the column names of the join table.
![]() ![]() |
<field name="collectionOfB" persistence-modifier="persistent"> |
class A {
private Collection myBs;
}
class B {
private Collection myAs;
}
The relation is Many-Many. The key "join-table" defines the name of the join table. If it is not specified the default table name is defined as the concatenation of the short class name (without the package name) of the source class, with the name of the collection field. The "source-foreign-keys" and "target-foreign-keys" extensions define the columns name of the join table.
![]() ![]() |
<class name="A"> |
class A {
private Set strings;
}
The persistent class 'A' references a set of String. The sets of String are stored into the table 'T_SET'.
![]() |
<class name="A" identity-type="datastore"> |
there are two cases of mapping for a Map field.
The example shows a map referenced by the A class ('mapOfBIndexedByString' field). The key of the map is a String value for which the column name can be specified by the 'index-sql-name' extension. The value type of the map is the persistent class B for which the mapping (column name) of the reference can be specified by the 'target-foreign-keys' extension. Finally the map identifier is always the identifier of the reference holder (the 'A' class). The column name of the map identifier can be specified by the extension 'source-foreign-keys'.
<class name="A">
<field name="mapOfBIndexedByString" persistence-modifier="persistent">
<map key-type="java.lang.String" value-type="B"/>
<extension vendor-name="speedo" key="join-table" value="MAP_TABLE_NAME"/>
<extension vendor-name="speedo" key="source-foreign-keys" value="PKA=FKA"/>
<extension vendor-name="speedo" key="target-foreign-keys" value="PKB=FKB"/>
<extension vendor-name="speedo" key="index-sql-name" value="KEY_COL_NAME"/>
<extension vendor-name="speedo" key="index-sql-type" value="VARCHAR(40)"/>
</field>
</class>
The example shows a map referenced by the 'A' class ('mapOfStringIndexedByLong' field). The key of the map is a Long value for which the column name can be specified by the 'index-sql_name' extension'. The value type of the map is a String for which the column name can be specified by the 'element-sql-name' extension. Finally the map identifier is always the identifier of the reference holder (the 'A' class). The column name of the map identifier can be specified by the extension 'source-foreign-keys'.
<class name="A">
<field name="mapOfStringIndexedByLong" persistence-modifier="persistent">
<map key-type="java.lang.Long" value-type="java.lang.String"/>
<extension vendor-name="speedo" key="join-table" value="MAP_TABLE_NAME"/>
<extension vendor-name="speedo" key="source-foreign-keys" value="PKA=FKA"/>
<extension vendor-name="speedo" key="element-sql-name" value="VALUE_COL_NAME"/>
<extension vendor-name="speedo" key="element-sql-type" value="VARCHAR(34)"/>
<extension vendor-name="speedo" key="index-sql-name" value="KEY_COL_NAME"/>
<extension vendor-name="speedo" key="index-sql-type" value="INT8"/>
</field>
</class>
The example shows a map referenced by the A class ('bf1_2_B' field). The key of the map is the 'f1' field of the B class. The value type of the map is the persistent class B.
<class name="A">
<field name="bf1_2_B" persistence-modifier="persistent">
<map key-type="java.lang.String" value-type="B"/>
<extension vendor-name="speedo" key="source-foreign-keys" value="PKA=FKA"/>
<extension vendor-name="speedo" key="key-field" value="f1"/>
</field>
</class>
<class name="B">
<field name="f1"/>
</class>
The second example is the same than the last with a bidirectional relation.
<class name="A">
<field name="bf1_2_B" persistence-modifier="persistent">
<map key-type="java.lang.String" value-type="B"/>
<extension vendor-name="speedo" key="source-foreign-keys" value="PKA=FKA"/>
<extension vendor-name="speedo" key="key-field" value="f1"/>
<extension vendor-name="speedo" key="reverse-field" value="myA"/>
</field>
</class>
<class name="B">
<field name="f1"/>
<field name="myA"/>
</class>
For each field referencing one or several persistent classes, it is possible to specify the reverse field of the relation if it exists. This information is very important: useless I/O are avoided based on the reverse field declaration. The fact that two fields are opposite depends on the semantics of the fields.
<class name="A">
<field name="refToB">
<extension vendor-name="speedo" key="reverse-field" value="refToA"/>
...
</field>
...
</class>
<class name="B">
<field name="refToA"/>
...
</class>
A foreign key declaraction (source or target) defines the column names of the foreign key according to the primary key structure. A foreign key declaraction is comma-separated list of equalities between the name of a primary key column and the name of a foreign key column.
The identifier of the referenced object (A) consists of a single column named "pka" and the column name of the foreign key column is named "fka".
![]() |
<class name="A"> |
The identifier of the referenced object (A) consists of two fields (FIRST_NAME, LAST_NAME). The corresponding names of the composite foreign key are (A_FN, A_LN).
![]() |
<class name="A"> |
This section is a summary of the previous ones. It enumerates (alphabetic order) all extensions available in Speedo.
Extension name | node level |
element-sql-name | Map orCollection fields mapping |
element-sql-type | Map or Collection fields mapping |
field-converter | Primitive fields mapping |
id | Class Mapping |
index-sql-name | Map or List fields mapping |
index-sql-type | Map or List fields mapping |
inheritance-filter | Class Mapping |
inheritance-key | Class Mapping |
inheritance-mapping | Class Mapping |
join-table | Map or Collection fields mapping |
key-field | Map fields mapping |
scale | Primitive fields mapping |
size | Primitive fields mapping |
source-foreign-keys | Reference, Collection or Map fields mapping, the foreign key declaraction |
sql-name | Class Mapping or Primitive fields mapping |
sql-seq-name | Class Mapping |
sql-seq-start | Class Mapping |
sql-seq-increment | Class Mapping |
sql-seq-cache | Class Mapping |
sql-type | Primitive fields mapping |
reverse-field | Reference, Collection, or Map fields mapping, the foreign key declaraction |
target-foreign-keys | Reference, Collection or Map fields mapping, the foreign key declaraction |
The speedo.properties file contains a data access section. In this section, the user can choose between the use of a JDBC driver directly or the use of a connection factory.
Enhance an application. Currently this task does not support already
enhanced classes: the user must manually remove the .class file of the
persistent classes each times this task is used.
Attribute | Description | Required |
confFile | This is the configuration file of the Speedo enhancer. Usually this file is the speedoc.properties provided in the distribution. | No |
output | Is the location of the .class of the user application. This is also the location where the Speedo files produced for the user persistent class is written. | Yes |
src | Is the location of the source of the user application. | Yes |
projectName | Is the name of the user project. If the user provides JORM persistent descriptor (legacy mapping case) like .pd files, the projectname must be specified and match the project name used in the .pd files. | No |
classpathref | Is the classpath containing Speedo, the user classes, and the configuration files (etc directory). | No |
logPropFile | Is the logging configuration file. It permits to choose another Monolog configuration file than the one provided in the etc directory | No |
failsonerror | indicates if the Speedo enhancer must stop after the first error or try to continue. The default value is true. | No |
The following example comes from the examples:
<property name="src" value="${basedir}/src"/>
<property name="build" value="${basedir}/build"/>
<property name="speedoDist" value="${basedir}/../.."/>
...
<path id="classpath">
<pathelement location="${speedoDist}/etc"/>
<pathelement location="${build}"/>
<fileset dir="${speedoDist}">
<include name="speedo.jar"/>
<include name="lib/log/log4j.jar"/>
<include name="lib/jdbc/postgres_jdbc2.jar"/>
</fileset>
</path>
...
<taskdef name ="speedo"
classname="org.objectweb.speedo.ant.AntSpeedo"
classpathref="classpath" />
...
<target="generation">
<delete dir="${build}"/>
<mkdir dir="${build}"/>
<javac srcdir="${src}" destdir="${build}" debug="on">
<classpath refid="classpath"/>
<include name="**/*.java"/>
</javac>
<speedo
confFile="${speedoDist}/etc/speedoc.properties"
output="${build}"
src="${src}"
projectName="invoice"
classpathref="classpath"/>
This section describes the properties of the
PersistencManagerFactory.
Some properties are not defined in the JDO specification and are
specific to Speedo. All of these properties are grouped in the
Speedo.properties configuration file.
Property name | Description | JDO / Speedo | Req | Value |
javax.jdo.PersistenceManagerFactoryClass | This property defines the name of the PersistenceManagerFactory class provided by Speddo. This value cannot be changed. | JDO | Y | "org.objectweb.speedo.Speedo" |
org.objectweb.speedo.mapperName | This property defines the name of mapper which must be used with the database. The default value is 'rdb.automatic'. For more information see the mappers section | Speedo | Y | "rdb.automatic" or "rdb.postgres" or "rdb.mysql" or ... |
Speedo alone (no application server) | ||||
javax.jdo.option.DriverName | This property defines the class name of the jdbc driver | JDO | Y | "org.postgresql.Driver" or "com.mysql.jdbc.Driver" or ... |
javax.jdo.option.ConnectionURL | This property defines the url of the database. | JDO | Y | "jdbc:postgresql:speedoTest" |
javax.jdo.option.ConnectionUserName | This property defines the user name authorized to access to the database. | JDO | Y | "smith" |
javax.jdo.option.ConnectionPassword | This property defines the password corresponding to user name authorized to access to the database. | JDO | Y | "myPassword" |
org.objectweb.speedo.connection.pool.min | This property permits to manage the minimal size of the pool of connection when Speedo uses directly a JDBC driver. The default value is 0. | Speedo | N | a positive integer value |
org.objectweb.speedo.connection.pool.max | This property permits to manage the maximal size of the pool of connection when Speedo uses directly a JDBC driver. The default value is 20. | Speedo | N | a positive integer value |
org.objectweb.speedo.connection.pool.ttl | This property defines the time to live of the unsused connection, ie the connection availlable in the pool. The value is declared in millisecond. The 0 value means the resource has no TTL. The 0 value is the default. | Speedo | N | 0 or a positive integer value |
org.objectweb.speedo.connection.pool.timeout | This property defines the time which the user agrees to wait a free connection from the pool. The value is declared in millisecond. The 0 value means that the user want to wait until a resource has been released. | Speedo | N | 0 or a positive integer value |
Integration of Speedo into a J2EE application server | ||||
javax.jdo.option.ConnectionFactoryName | This property is the jndi name of the connection factory to use to access the data support. | JDO | Y | "myConnFactJndiNAme" |
org.objectweb.speedo.jca.TMName | This property is the jndi name of a registered transaction manager. For more information see the section about the application server integration | Speedo | Required when is integrated into an application server | "javax.transaction.TransactionManger" |
Memory Cache Configuration | ||||
javax.jdo.option.IgnoreCache | Indicates if queries and extends must ingore the instance modified in memory and not yet committed into the support. The default value is 'true' | JDO | N | 'true' or 'false' |
javax.jdo.option.RestoreValues | The management of this option is not supported. The only supported value is "false" | |||
javax.jdo.option.RetainValues | This property indicates if the peristent object are ketpt in memory at commit time. The default value is 'true' | Speedo | N | 'true' or 'false' |
org.objectweb.speedo.cache.policy | It defines the replacement politic of the memorry cache. The possible values are: LRU, MRU or FIFO. The default value is LRU | Speedo | N | LRU, MRU or FIFO |
org.objectweb.speedo.cache.size | This property permits to manage the size of the cache of memory instances. The default value is "nolimit", that means that the cache have not a maximum size. | Speedo | N | "nolimit" or a positive integer value |
org.objectweb.speedo.cache.autoCleanSize | This property defines the number of cache entry to free when the cache of memory instance is full or when the threshold is reached. The value can be a percent of the maximal cache size (ex: "10%") or an absolute value (ex: "456"). The default value is a percent: "7%". | Speedo | N | a positive integer value between 0 and the cache size or a percent (ex: 12%) |
org.objectweb.speedo.cache.autoCleanThreshold | Is the number of entries since the cache must try to evict entries. The number of entries to evict is specified by the 'autoCleanSize' property. The possible values are absolute values (234) or a percent of the maximal cache size (75%). By default there is no threshold, then there is no auto cleaning process. | Speedo | N | a positive integer value between 0 and the cache size or a percent (ex: 80%) |
Configuration of the Persistence manager pool | ||||
org.objectweb.speedo.peristencemanager.pool.min | This property permits to manage the minimal size of the pool of PersistenceManager. The default value is 0. | Speedo | N | a positive integer value |
org.objectweb.speedo.peristencemanager.pool.max | This property permits to manage the maximal size of the pool of PersistenceManager. The default value is "nolimit". | Speedo | N | "nolimit" or a positive integer value |
org.objectweb.speedo.peristencemanager.pool.ttl | This property defines the time to live of the unsused persistence manager, ie the persistence manager availlable in the pool. The value is declared in millisecond. The 0 value means the resource has no TTL. The 0 value is the default. | Speedo | N | 0 or a positive integer value |
org.objectweb.speedo.peristencemanager.pool.timeout | This property defines the time which the user agrees to wait a free peristence manager from the pool. The value is declared in millisecond. The 0 value means that the user want to wait until a resource has been released. | Speedo | N | 0 or a positive integer value |
Query Management Configuration | ||||
org.objectweb.speedo.query.prefetch.query | This property permits to desactive the data prefetching on queries. The default value is 'on'. | Speedo | N | 'on' or 'off' |
org.objectweb.speedo.query.prefetch.extent | This property permits to desactive the data prefetching on extents. The default value is 'on'. | Speedo | N | 'on' or 'off' |
org.objectweb.speedo.compiledquery.cache.policy | It defines the replacement politic of the compiled query cache. The possible values are: LRU, MRU or FIFO. The default value is LRU | Speedo | N | LRU, MRU or FIFO |
org.objectweb.speedo.compiledquery.cache.size | This property permits to manage the size of the cache of compiled query instances. The default value is "nolimit", that means that the cache have not a maximum size. | Speedo | N | "nolimit" or a positive integer value |
org.objectweb.speedo.compiledquery.cache.autoCleanSize | This property defines the number of cache entry to free when the cache of compiled query instances is full or when the threshold is reached. The value can be a percent of the maximal cache size (ex: "10%") or an absolute value (ex: "456"). The default value is a percent: "7%". | Speedo | N | a positive integer value between 0 and the cache size or a percent (ex: 12%) |
org.objectweb.speedo.compiledquery.cache.autoCleanThreshold | Is the number of entries since the cache must try to evict entries. The number of entries to evict is specified by the 'autoCleanSize' property. The possible values are absolute values (234) or a percent of the maximal cache size (75%). By default there is no threshold, then there is no auto cleaning process. | Speedo | N | a positive integer value between 0 and the cache size or a percent (ex: 80%) |
Other properties | ||||
javax.jdo.option.Multithreaded | Indicates if several threads can manipulate a same PersistenceManager instance in same time (concurrency). The default value is 'false' | JDO | N | 'true' or 'false' |
org.objectweb.speedo.mappingStructure | This property specifies the behavior of Speedo on the mapping
structures (ex SQL tables). The possible behavior are the following:
Note: When speedo is integrated into an application server, this property must equal DO_NOTHING. Indeed it is rarely possible to create data structure (SQL relations) inside an XA transaction. If you specify another value, Speedo will force the value to DO_NOTHING and will log a warning about it. |
Speedo | N | DO_NOTHING or CREATE_IF_REQUIRED or FORCE_CREATE or DELETE_DATA |
org.objectweb.speedo.txStatistic | This property indicates if Speedo must build statistics about the transactions. | Speedo | N | 'true' or 'false' |
javax.jdo.option.NontransactionalRead | This option is not supported. The value is "false" | |||
javax.jdo.option.NontransactionalWrite | This option is not supported. The value is "false" |
There are several configuration files provided with Speedo. Indeed Speedo uses several ObjectWeb projects/frameworks. All these configuration files must be available at the root of the classpath. In general most Speedo users only have to manage one file: speedo.properties. This section also describes in the second part the other configuration files.
This file is used at runtime for the properties of the PersistenceManagerFactory. Therefore this properties file can be loaded into a java.util.Properties instance in order to fetch a PersistanceManagerFactory, as illustrated by the following example:
Properties p = new Properties();
p.load(new FileInputStream("speedo.properties"));
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(p);
The file must be available at the root of the classpath during the
runtime. For more information about the propeties of the
PersistanceManagerFactory see the section The PersistenceManagerFactory properties of this
documentation.
This file is used to configure logging. It must be available at the
root of the classpath during the enhancement and at runtime. For more
information see the section The logging
in this documentation.
This file is the configuration file of the tool P6Spy permiting to log the SQL call throught the JDBC driver. To activate this logging the user must
logger.org.objectweb.speedo.mapper.mapper.sql.level DEBUGin the monolog.properties file.
The librairies of the p6spy tool are included in the speedo.jar.
The Speedo implementation respects the component model defined in
ObjectWeb: Fractal. Speedo
uses Julia as
implementation of this model. The julia.cfg file is the configuration
file of Julia. It must be available in the classpath (root position)
during the enhancement and at runtime.
To manage the I/O with the support Speedo uses JORM. The jorm.properties file is
the JORM configuration file. It defines the supported mapper. It must
be available in the classpath during the enhancement and at runtime.
The persistent objects are stored in a persistence support. Thanks to JORM, it is possible to store persistent objects into various types of persistence support. Each persistence support type is represented by a mapper. For a relationnal database the mapper is "rdb". Due to the lack of conformance of JDBC drivers, JORM provides adapters to the JDBC specification for some databases. JORM provides also an automatic mechanism to discover the database product via a metadata provided by connections. If the auto detection fails you have to specify the mapper name mathcing the database product. The following table shows the supported persistence support and the associated mapper names:
Persistence support | Mapper name | Status |
Oracle (<=8.x) | rdb.oracle8 | OK |
Oracle (>=9.x) | rdb.oracle | OK |
PostgresSQL (>= 7.2) | rdb.postgres | OK |
Mysql | rdb.mysql | OK |
MS Sql Server | rdb.sqlserver | OK |
Firebird | rdb.firebird | Testing |
McKoi | rdb.mckoi | OK |
Sap DB | rdb.sapdb | Testing |
Sybase | rdb.sybase | Testing |
Hsql | rdb.hsql | OK |
Driver conform to JDBC specification | rdb | OK |
For more information about the adapters, see the JORM framework. Note that writing an adapter for a new relational database
is a very easy task.
The JORM project provides a RdbAdapter module permitting to easily
write RdbAdapter. Download the product on the
JORM download page.
When your new RdbAdapter works fine, you can integrate the
ow_jorm_rdb_adapter.jar into Speedo (lib directory in the distribution).
Like other ObjectWeb products, Speedo uses a logging API in order to be independant from implementations. Monolog provides wrappers to the usual logging systems like log4j or the logging system of jdk (since 1.4). There is a logging configuration file which does not depends on the logging system. This file is named "monolog.properties". Speedo uses Monolog in the automatic mode:
For more information about Monolog and its configuration file see the Monolog
documentation
Speedo supports the following types, which means that a persistent field can be declared with one of these types:
Speedo can be integrated into application servers as a resource
adapter (JCA Connector SUN specification). Then, to use Speedo inside
an application server, you have to use the rar file provided in the
Speedo binary distribution.
To use Speedo in an application server with transactions demarcated by
the EJB container, the transaction manager instance (implements
javax.transaction.TransactionManager) MUST be registered into JNDI. The
JNDI name can be assigned to the property
org.objectweb.speedo.jca.TMName in the 'speedo.properties'
configuration file. If no name is specified, several attempts are done
with classical JNDI names used in some application servers:
Application Server | JNDI name of TransactionManager instance |
JOnAS | javax.transaction.UserTransaction |
JBoss | java:/TransactionManager |
WebLogic | javax.transaction.TransactionManager |
WebSphere | jta/usertransaction |
Orion | java:comp/UserTransaction |
Data structures: Speedo is able, through Jorm, to create the data structure during the first use of a persistent class. But some data support does not permit to create data structures (SQL relations) inside XA transactions. Then Speedo allows only the DO_NOTHING value for the property org.objectweb.speedo.mappingStructure. Then you should read the Creation of the data structure section in order to create the data structure before the application starting.
JOnAS case: In case of you want to integrate Speedo into
JOnAS, you have to use compatible versions. Indeed, JOnAS and Speedo
use common frameworks (JORM, MEDOR, Perseus) and the some classes are
already available in the server. In addition, a small rar file
dedicated to JOnAS is also provided with the Speedo distribution.
Speedo through Jorm is able to create automaticaly the data
structure on the persistent support. This feature is activated with
regards to the property
org.objectweb.speedo.mappingStructure of the speedo.properties
configuration file.
However in application servers with XA connector some persistent
supports are able to create data structure (SQL relations for example)
inside an XA transaction. Then we advice you to create data structures
before to launch your application. To do this Speedo provides a simple
tool class named 'org.objectweb.speedo.tools.DataStructureCreation'. An
ant target 'createDataStruct' is also provided inside the build.xml of
the speedo distribution and inside the bank example. This target
launches the tools class with regards to the following usage:
DataStructureCreation (<class name to initialize> | <.jdo file name>)*
[-Djavax.jdo.option.DriverClassName=<driver class name>]
[-Djavax.jdo.option.ConnectionURL=<database url>]
[-Djavax.jdo.option.ConnectionUserName=<user name>]
[-Djavax.jdo.option.ConnectionPassword=<user password>]
Speedo supports detach/attach operations. Once made
persistent, an
object can be detached from the cache : the user gets a copy of the
persistent instance. The copy can be modified either
in the same JVM or in a different JVM. Then, the copy can be
re-attached: this operation commits the changes on the cache.
To enable such operations on objects, the class must be defined as
detachable in the jdo file as follows:
<class name="Player" identity-type="application" detachable="true">
The following code sample shows the way to perform a detach
operation. This code is based on a Team class containing a collection
of Players and a Coach.
//firstly, define a team with 2 players and a coach
Team team = new Team("Bordeaux",null,null);
Collection players = new ArrayList();
Player player1 = new Player("p1", t, 25);
players.add(player1);
Player player2 = new Player("p2", t, 32);
players.add(player2);
team.setPlayers(players);
Coach coach = new Coach("c1", 5, team);
team.setCoach(coach);
//then, get the persistence manager and make the team persistent
PersistenceManager pm = pmf.getPersistenceManager();
pm.currentTransaction().begin();
pm.makePersistent(team);
pm.currentTransaction().commit();
//finally, detach the team
Team copyOfTeam = (Team) ((ProxyManager)pm).detachCopy((Object)team);
pm.close();
The detach operation can be performed indifferently within or
outside a transaction. When detaching an object, all references to
other persistent objects are replaced by the corresponding detached
copies.
Detaching an object not yet persistent makes it persistent before
returning a copy of the object. When detaching a persistent-new or a
persistent-dirty object, updates of this object are flushed prior to
detachment: if the transaction in which the flush is performed rolls
back, then the detached copy becomes invalid (no re-attachment is
allowed).
The attach operation has to be performed within an active transaction. When performing an attach, changes made to a copy while detached are applied to the corresponding persistent instance in the cache. If the object being attached is not yet persistent, it is firstly made persistent.
The following code sample shows the way to perform an attach
operation.
This code is also based on a Team class containing a collection of
Players
and a Coach.
//firstly, define a team with 2 players and a coach
Team team = new Team("Bordeaux",null,null);
Collection players = new ArrayList();
Player player1 = new Player("p1", team, 25);
players.add(player1);
Player player2 = new Player("p2", team, 32);
players.add(player2);
team.setPlayers(players);
Coach coach = new Coach("c1", 5, team);
team.setCoach(coach);
//then, get the persistence manager and make the team persistent
PersistenceManager pm = pmf.getPersistenceManager();
pm.currentTransaction().begin();
pm.makePersistent(team);
pm.currentTransaction().commit();
//detach the team and modify the detached copy
Team copyOfTeam = (Team) ((ProxyManager)pm).detachCopy((Object)team);
copyOfTeam.getCoach().setExperience(99);
//finally attach the team
pm.currentTransaction().begin();
Team attachedTeam = (Team) ((ProxyManager)pm).attachCopy((Object)copyOfTeam,false);
pm.currentTransaction().commit();
pm.close();
The object returned by the attach method is the persistent object
corresponding to the detached instance.
A fetch group defines a particular loaded state for an object graph.
It specifies fields to be loaded for all the instances in the graph.
Speedo uses fetch groups for detach, refresh and retrieve operations.
public class Person{
String name;
int age;
Address address;
Set children;
}
public class Address{
String street;
String city;
Country country;
}
public class Country{
String code;
String name;
}
<class name="Person" ...>
...
<fetch-group name="myFirstFG">
<field name="name"/>
<field name="age"/>
<field name="address"/>
</fetch-group>
...
</class>
<class name="Person" ...>Activating this fetch group, the address field will be first loaded with only the country field. And then, the country field will be loaded with only the code field.
...
<fetch-group name="referenceFG">
<field name="address.country.code"/>
</fetch-group>
...
</class>
<class name="Person" ...>The name and age fields will be loaded because of the nested fetch group "values" and the children field will also be loaded.
...
<fetch-group name="nestedFG">
<fetch-group name="values"/>
<field name="children"/>
</fetch-group>
...
</class>
<class name="Person" ...>The name, age, address will be loaded and it will be the same for the children of the person being detached, refreshed or retrieved. The children of the children will not be loaded.
...
<fetch-group name="depthFG">
<fetch-group name="default"/>
<field name name="address"/>
<field name="children" depth="1"/>
</fetch-group>
...
</class>
<class name="Person" ...>Let's consider that the active fetch group is the "detail" fetch group. The fields name, age and address will be loaded for the person being detached, refreshed or retrrieved. For the field children, the fetch group "list" will be used: the name and age of each child will be loaded.
...
<fetch-group name="list">
<field name="name"/>
<field name name="age"/>
</fetch-group>
<fetch-group name="detail">
<fetch-group name="default"/>
<field name="address"/>
<field name="children" fetch-group="list"/>
</fetch-group>
...
</class>
public class Node{
String name;
Map edges; //name -> EdgeWeight
}
public class EdgeWeight{
int weight;
}
<class name="Node" ...>If the "keyValue" fetch group is active, both keys and values of elements in the map of the node object will be loaded.
...
<fetch-group name="keyValue">
<field name="edges#key"/>
<field name="edges#value"/>
</fetch-group>
<fetch-group name="keyOnly">
<field name="edges#key"/>
</fetch-group>
...
</class>
PersistenceManager pm = pmf.getPersistenceManager();The application is then ready to detach, refresh and retrieve instances using the fetch groups.
FetchPlan fp = new SpeedoFetchPlan();
fp.addGroup("detail").removeGroup("default"); //only the detail fg is active
((ProxyManager)pm).setFetchPlan(fp);