|  |  |  | License Codehaus OpenEJB OpenJMS OpenORB Tyrex

Old releases
General
Release 1.3
Release 1.3rc1
Release 1.2

Main
Home
About
Features
Download
Dependencies
Reference guide
Publications
JavaDoc
Maven 2 support
Maven 2 archetypes
DTD & Schemas
Recent HTML changes
News Archive
RSS news feed
Project Wiki

Development/Support
Mailing Lists
SVN/JIRA
Contributing
Support
Continuous builds
Prof. services

Related projects
Spring ORM support
Spring XML factories
WS frameworks

XML
XML

XML Code Generator
XML Code Generator

JDO
Introduction
First steps
Using JDO
JDO Config
Types
JDO Mapping
JDO FAQ
JDO Examples
JDO HOW-TOs
Tips & Tricks
Other Features
JDO sample JAR

Tools
Schema generator

Advanced JDO
Caching
OQL
Trans. & Locks
Design
KeyGen
Long Trans.
Nested Attrs.
Pooling Examples
LOBs
Best practice

DDL Generator
Using DDL Generator
Properties
Ant task
Type Mapping

More
The Examples
3rd Party Tools
JDO Tests
XML Tests
Configuration

About
License
User stories
Contributors
Marketplace
Status, Todo
Changelog
Library
Contact
Project Name

## Castor JDO code samples

Documentation Author(s):
Werner Guttmann

Introduction
Java class files
DDL
Object Mappings
Read-only fields
Transient fields
Relations
1:1 relation
1:M relation
M:N relation
Extend relation & polymorphism
OQL samples

## Introduction

This document provides object mapping examples and the corresponding Java objects and DDL for the database table.

### Java class files

The following fragment shows the Java class declaration for the `Product` class:

    package myapp;

    public class Product {

        private int       _id;

        private String    _name;

        private float     _price;

        private ProductGroup _group;

        public int getId() { ... }

        public void setId( int anId ) { ... }

        public String getName() { ... }

        public void setName( String aName ) { ... }

        public float getPrice() { ... }

        public void setPrice( float aPrice ) { ... }

        public ProductGroup getProductGroup() { ... }

        public void setProductGroup( ProductGroup aProductGroup ) { ... }
    }

The following fragment shows the Java class declaration for the `ProductGroup` class:

    public class ProductGroup {

        private int       _id;

        private String    _name;

        public int getId() { ... }

        public void setId( int id ) { ... }

        public String getName() { ... }

        public void setName( String name ) { ... }

    }

### DDL

The following sections show the DDL for the relational database tables `PROD`, `PROD_GROUP`, and `PROD_DETAIL`:

`PROD`:

    create table prod (
      id        int           not null,
      name      varchar(200)  not null,
      price     numeric(18,2) not null,
      group_id  int           not null
    );

`PROD_GROUP`:

    create table prod_group (
      id        int           not null,
      name      varchar(200)  not null
    );

`PROD_DETAIL`:

    create table prod_detail (
      id        int           not null,
      prod_id   int           not null,
      name      varchar(200)  not null
    );

### Object Mappings

The following code fragment shows the object mapping for the `ProductGroup` class:

    <?xml version="1.0"?>
    <!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Object Mapping DTD Version 1.0//EN"
                             "http://castor.org/mapping.dtd">
    <mapping>

      <class name="myapp.ProductGroup" identity="id">

        <description>Product group</description>

        <map-to table="prod_group" xml="group" />

        <field name="id" type="integer" >
          <sql name="id" type="integer"/>
        </field>

        <field name="name" type="string">
          <sql name="name" type="char" />
        </field>

      </class>

    </mapping>

As a result of that declaration, Castor JDO will create the following SQL statements for creating, deleting, loading and updating instances of `ProductGroup`:

    create: INSERT INTO prod_group (id, name) VALUES (?,?)
    delete: DELETE FROM prod_group WHERE id=?
    load:   SELECT prod_group.id, prod_group.name FROM prod_group WHERE prod_group.id=?;
    update: UPDATE prod_group SET name=? WHERE id=?

#### Read-only fields

To declare the name field read-only, the field definition above for the field name needs to be changed to:

      <class name="myapp.ProductGroup" identity="id">

        ...
        <field name="name" type="string">
          <sql name="name" type="char" read-only="true" />
        </field>

      </class>

As a result of that declaration, Castor JDO creates the following SQL statements for creating, deleting, loading and updating instances of `ProductGroup`:

    create: INSERT INTO prod_group (id) VALUES (?)
    delete: DELETE FROM prod_group WHERE id=?
    load:   SELECT prod_group.id, prod_group.name FROM prod_group WHERE prod_group.id=?;
    update: no statement will be generated

#### Transient fields

To declare the name field transient with regards to persistence, above field definition for the field name needs to be changed to:

      <class name="myapp.ProductGroup" identity="id">

        ...
        <field name="name" type="string" >
          <sql name="name" type="char" transient="true" />
        </field>

      </class>

### Relations

#### 1:1 relation

The following code fragment shows the mapping file for the Product class. Apart from the simple field declarations, this includes a simple 1:1 relation between `Product` and `ProductGroup`, where every product instance is associated with a `ProductGroup`:

        <class name="myapp.Product" identity="id">

            <map-to table="prod" />

            <field name="id" type="integer">
                <sql name="id" type="integer" />
            </field>

            <field name="name" type="string">
                <sql name="name" type="char" />
            </field>

            <field name="price" type="float">
                <sql name="price" type="numeric" />
            </field>

            <field name="group" type="myapp.ProductGroup" >
                <sql name="group_id" />
            </field>

            <field name="details" type="myapp.ProductDetail"
                   collection="vector">
               <sql many-key="prod_id"/>
            </field>

            <field name="categories" type="myapp.Category" collection="vector">
               <sql name="category_id"
                    many-table="category_prod" many-key="prod_id" />
            </field>

        </class>

#### 1:M relation

The following code fragment shows (again) the mapping file for the `Product` class. The field definition highlighted shows how to declare a 1:M relation between `Product` and `ProductDetail`, where every product instance is made up of many `ProductDetails`:

        <class name="myapp.Product" identity="id">

            <map-to table="prod" />

            <field name="id" type="integer">
                <sql name="id" type="integer" />
            </field>

            <field name="name" type="string">
                <sql name="name" type="char" />
            </field>

            <field name="price" type="float">
                <sql name="price" type="numeric" />
            </field>

            <field name="group" type="myapp.ProductGroup" >
                <sql name="group_id" />
            </field>

            <field name="details" type="myapp.ProductDetail" collection="vector">
               <sql many-key="prod_id"/>
            </field>

            <field name="categories" type="myapp.Category" collection="vector">
               <sql name="category_id"
                    many-table="category_prod" many-key="prod_id" />
            </field>
        </class>

The following code fragment shows the corresponding mapping entry for the `ProductDetail` class that defines the second leg of the 1:M relation between `Product` and `ProductDetail`.

      <class name="myapp.ProductDetail" identity="id" depends="myapp.Product" >

        <description>Product detail</description>

        <map-to table="prod_detail" xml="detail" />

        <field name="id" type="integer">
          <sql name="id" type="integer"/>
        </field>

        <field name="name" type="string">
          <sql name="name" type="char"/>
        </field>

        <field name="product" type="myapp.Product">
          <sql name="prod_id" />
        </field>

      %lt;/class>

#### M:N relation

The following code fragment shows (again) the mapping file for the `Product` class. The field definition highlighted shows how to declare a M:N relation between `Product` and `ProductCategory`, where many products can be mapped to many product categories:

        <class name="myapp.Product" identity="id">

            <map-to table="prod" />

            <field name="id" type="integer">
                <sql name="id" type="integer" />
            </field>

            <field name="name" type="string">
                <sql name="name" type="char" />
            </field>

            <field name="price" type="float">
                <sql name="price" type="numeric" />
            </field>

            <field name="group" type="myapp.ProductGroup" >
                <sql name="group_id" />
            </field>

            <field name="details" type="myapp.ProductDetail" collection="vector">
               <sql many-key="prod_id">/>
            </field>

            <field name="categories" type="myapp.Category" collection="vector">
               <sql name="category_id"
                    many-table="category_prod" many-key="prod_id" />
            </field>

        </class>

The following code fragment shows the corresponding mapping entry for the `ProductCategory` class that defines the second leg of the M:N relation between `Product` and `Category`.

      <class name="myapp.Category" identity="id">

        <description>
            A product category, any number of products can belong to
            the same category, a product can belong to any number of
            categories.
        </description>

        <map-to table="category" xml="category" />

        <field name="id" type="integer">
          <sql name="id" type="integer"/>
        </field>

        <field name="name" type="string">
          <sql name="name" type="char"/>
        </field>

        <field name="products" type="myapp.Product" collection="vector">
          <sql name="prod_id"
               many-table="category_prod" many-key="category_id" />
        </field>

      </class>

### Extend relation & polymorphism

As of release 0.9.9, Castor supports polymorphic queries on extend hierarchies. (That is, hierarchies where some entities "extend" other entities.) To highlight this new feature, let's add two new classes to what we have currently.

    package myapp;

    public class Computer extends Product {

        private int       _id;

        private String    _make;

        public int getId() { ... }

        public void setId( int anId ) { ... }

        public String getmake() { ... }

        public void setMake( String aMake ) { ... }

    }

    public class Car extends Product {

        private int       _id;

        private Date    _registeredIn;

        public int getId() { ... }

        public void setId( int anId ) { ... }

        public Date getRegisteredIn() { ... }

        public void setRegisteredIn( Date aRegisteredIn ) { ... }
    }

The corresponding DDL statements for the relational database tables `COMP` and `CAR` would look as follows:

`COMP`:

    create table comp (
      id        int           not null,
      make      varchar(200)  not null
    );

`CAR`:

    create table car (
      id        int           not null,
      regIn     int           not null
    );

Based upon the mapping defined for the `Product` class as shown above, the following code fragment shows the mapping for the `Computer` and `Car` classes.

        <class name="myapp.Computer" extends="myapp.Product" identity="id">

            <map-to table="COMP" />

            <field name="id" type="integer">
                <sql name="id" type="integer" />
            </field>

            <field name="make" type="string">
                <sql name="make" type="char" />
            </field>

        </class>

        <class name="myapp.Car" extends="myapp.Product" identity="id">

            <map-to table="CAR" />

            <field name="id" type="integer">
                <sql name="id" type="integer" />
            </field>

            <field name="registeredIn" type="date">
                <sql name="regIn" type="long" />
            </field>

        </class>

Based upon this mapping, it is possible to execute the following OQL queries against this class model:

    OQLQuery query = d.getOQLQuery("SELECT c FROM myapp.Computer c");

To return all computers:

    OQLQuery query = d.getOQLQuery("SELECT c FROM myapp.Computer c WHERE c.make = $");

To return all computers of a particular make:

    OQLQuery query = d.getOQLQuery("SELECT p FROM myapp.Product p");

To return all products (where Castor will return the actual object instances, i.e. a `Computer` instance if the object returned by the query is of type `Computer` or a `Car` instance if the object returned by the query is of type `Car`):

    OQLQuery query = d.getOQLQuery("SELECT p FROM myapp.Product p WHERE p.group.name = $");

To return all products that belong to the specified product group (where Castor will return the actual object instances, i.e. a `Computer` instance if the object returned by the query is of type `Computer` or a `Car` instance if the object returned by the query is of type `Car`):

### OQL samples

Based upon above definitions, here are a few OQL sample queries that highlight various artifacts of the OQL support of Castor JDO.

To Be Written

<notice> Copyright © 1999-2005 ExoLab Group, Intalio Inc., and Contributors. All rights reserved. </notice>
<notice> Java, EJB, JDBC, JNDI, JTA, Sun, Sun Microsystems are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and in other countries. XML, XML Schema, XSLT and related standards are trademarks or registered trademarks of MIT, INRIA, Keio or others, and a product of the World Wide Web Consortium. All other product names mentioned herein are trademarks of their respective owners. </notice>