ODF Documents

DataNucleus supports persisting/retrieving objects to/from Open Document Format (ODF) documents (using the datanucleus-odf plugin). Such documents can then be used in applications like OpenOffice and KOffice. It makes use of the ODF Toolkit project. If you wish to help out in this effort either by contributing or by sponsoring particular functionality please contact us via the DataNucleus Forum.

Datastore Connection

DataNucleus supports file-based persistence currently.

The following persistence properties will connect to a local file on your local machine

datanucleus.ConnectionURL=odf:file:myfile.ods

replacing "myfile.ods" with your filename, which can be absolute or relative

So you create your PersistenceManagerFactory or EntityManagerFactory with these properties. Thereafter you have the full power of the JDO or JPA APIs at your disposal, for your ODF datastore.



Queries

Access Platform allows you to query the objects in the datastore using the following

  • JDOQL - language based around the objects that are persisted and using Java-type syntax
  • JPQL - language based around the objects that are persisted and using SQL-like syntax


Access to ODF 'connection'

When using JDO you can do the following to get hold of the native "OdfDocument" object

    tx.begin();
    ...

    // Get hold of native connection
    JDOConnection jdoConn = pm.getDataStoreConnection();
    OdfDocument doc = (OdfDocument)jdoConn.getNativeConnection();
    ... (do something with the document)
    jdoConn.close(); // Hands it back to JDO
    
    tx.commit();

Sadly JPA doesn't have such a feature



Mapping : ODF Document Mapping

ODF document support assumes that objects of a class are persisted to a particular "sheet" of an ODF spreadsheet. Similarly a field of a class is persisted to a particular "column" index of that "sheet". This provides the basis for ODF persistence. When persisting a Java object to an ODF spreadsheet clearly the user would like some control over what worksheet a class is persisted to, and to what column number a field is persisted. DataNucleus provides extension metadata tags to allow this control. Here's an example, using JDO XML metadata

<jdo>
    <package name="mydomain">
        <class name="Person" detachable="true" table="People">
            <field name="id">
                <column position="0"/>
            </field>
            <field name="firstName">
                <column position="1"/>
            </field>
            <field name="lastName">
                <column position="2"/>
            </field>
            ...
        </class>
    </package>
</jdo>

Things to note.

  • We use the table attribute of class to define the name of the sheet to use for persistence of this class.
  • We use the column attribute to define the column name to use for the field (otherwise will be the field name).
  • The position of the column defines the position in the worksheet of this column. This is new in JDO3.1 and is optional (the default is to put the fields in alphabetical order).

Here's the same example using JDO Annotations

@PersistenceCapable(table="People")
public class Person
{
    @Column(position=0)
    long id;

    @Column(position=1)
    String firstName;

    @Column(position=2)
    String lastName;

    ...
}

Here's the same example using JPA Annotations (with DataNucleus @Extension/@Extensions annotations)

@Entity
@Table(name="People")
public class Person
{
    @Id
    @ColumnPosition(0)
    long id;

    @ColumnPosition(1)
    String firstName;

    @ColumnPosition(2)
    String lastName;

    ...
}


Mapping : Relationships

Obviously a spreadsheet cannot store related objects directly since each object is a row of a particular spreadsheet table. DataNucleus gets around this by storing the String-form of the identity of the related object in the relation cell. See below for an example of the resultant spreadsheet of a class Person that has a 1-1 relation, and a 1-N relation.

In the above example, column 'C' is the 1-N relation, and so elements of the collection are stored as comma-separated object identities. In the same example, column 'D' is the 1-1 relation and the related object is the object identity. When the spreadsheet is read back in again the related object is found.



Mapping : Table Headers

A typical spreadsheet has many rows of data. It contains no names of columns tying the data back to the input object (field names). DataNucleus allows an extension specified at class level called include-column-headers (should be set to true). When the table is then created it will include an extra row (the first row) with the column names from the metadata (or field names if no column names were defined). For example