package jdo;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.Statement;
import myapp.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.exolab.castor.jdo.Database;
import org.exolab.castor.jdo.JDOManager;
import org.exolab.castor.jdo.OQLQuery;
import org.exolab.castor.jdo.QueryResults;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.mapping.xml.ClassMapping;
import org.exolab.castor.mapping.xml.FieldMapping;
import org.exolab.castor.mapping.xml.MappingRoot;
import org.exolab.castor.xml.Marshaller;
/**
* This example is only intended to show how castor can be set up
* in a standalone environment. For detailed examples on the mapping file,
* database schemas, supported features and their expected behaviors,
* please consult the JDO test cases instead. The JDO test cases can be
* found in the full CVS snapshot and located under the directory of
* src/tests/jdo and src/tests/myapp.
*/
public class Test
{
private static final String DATABASE_NAME = "test";
private static Log LOG = LogFactory.getLog(Test.class);
public static final String JDO_CONFIG_FILE = "jdo-conf.xml";
public static final String MAPPING_FILE = "mapping.xml";
public static final String USAGE_INSTRUCTIONS = "Usage: example jdo";
private Mapping _mapping;
private JDOManager _jdo;
public static void main( String[] args )
{
try
{
Test test = new Test();
test.setup();
test.run();
}
catch (Exception except)
{
LOG.error(except, except);
}
}
public Test () throws IOException, MappingException {
// Load the mapping file
_mapping = new Mapping(getClass().getClassLoader());
_mapping.loadMapping(getClass().getResource(MAPPING_FILE));
String jdoConf = getClass().getResource(JDO_CONFIG_FILE).toString();
JDOManager.loadConfiguration(jdoConf);
_jdo = JDOManager.createInstance(DATABASE_NAME);
}
public void setup () throws Exception {
Database db = _jdo.getDatabase();
db.begin();
Connection connection = db.getJdbcConnection();
Statement statement = connection.createStatement();
statement.executeUpdate("create table prod (id int not null, name varchar(200) not null, price numeric(18,2) not null, group_id int not null)");
statement.executeUpdate("create table prod_group (id int not null, name varchar(200) not null)");
statement.executeUpdate("create table prod_detail (id int not null, prod_id int not null, name varchar(200) not null)");
statement.executeUpdate("create table computer (id int not null, cpu varchar(200) not null)");
statement.executeUpdate("create table category (id int not null, name varchar(200) not null)");
statement.executeUpdate("create table category_prod (prod_id int not null, category_id int not null)");
db.commit();
db.close();
}
public void run() throws Exception
{
Database db;
Product product = null;
ProductGroup group;
Category category;
ProductDetail detail;
Computer computer = null;
OQLQuery productOql;
OQLQuery groupOql;
OQLQuery categoryOql;
OQLQuery computerOql;
QueryResults results;
db = _jdo.getDatabase();
db.begin();
LOG.info( "Begin transaction to remove Product objects" );
// Look up the products and if found in the database,
// delete them from the database
productOql = db.getOQLQuery( "SELECT p FROM myapp.Product p WHERE p.id = $1" );
for ( int i = 4; i < 10; ++i )
{
LOG.debug( "Executing OQL" );
productOql.bind( i );
results = productOql.execute();
while ( results.hasMore() )
{
product = ( Product ) results.next();
LOG.debug( "Deleting existing product: " + product );
db.remove( product );
}
}
LOG.info( "End transaction to remove Product objects" );
db.commit();
db.begin();
LOG.info( "Begin transaction to remove Computer object" );
// Look up the computer and if found in the database,
// delete ethis object from the database
computerOql = db.getOQLQuery( "SELECT c FROM myapp.Computer c WHERE c.id = $1" );
computerOql.bind( 44 );
results = computerOql.execute();
while ( results.hasMore() )
{
computer = ( Computer ) results.next();
LOG.debug( "Deleting existing computer: " + computer );
db.remove( computer );
}
LOG.info( "End transaction to remove Computer objects" );
db.commit();
db.begin();
LOG.info( "Begin transaction to remove Category objects" );
// Look up the categories and if found in the database,
// delete this object from the database
categoryOql = db.getOQLQuery( "SELECT c FROM myapp.Category c WHERE c.id = $1" );
// Still debugging this area because deletion of Category objects is not
// working the second time around
for ( int i = 7; i < 10; ++i )
{
categoryOql.bind( i );
results = categoryOql.execute();
while ( results.hasMore() )
{
category = ( Category ) results.next();
LOG.debug( "Deleting existing category: " + category );
db.remove( category );
}
}
LOG.info( "End transaction to remove Category objects" );
db.commit();
db.begin();
LOG.info( "Begin transaction: one-to-one, one-to-many, and dependent relations" );
// If no such group exists in the database, create a new
// object and persist it
groupOql = db.getOQLQuery( "SELECT g FROM myapp.ProductGroup g WHERE id = $1" );
groupOql.bind( 3 );
results = groupOql.execute();
if ( ! results.hasMore() )
{
group = new ProductGroup();
group.setId( 3 );
group.setName( "a group" );
db.create( group );
LOG.debug( "Creating new group: " + group );
}
else
{
group = ( ProductGroup ) results.next();
LOG.debug( "Query result: " + group );
}
// If no such product exists in the database, create a new
// object and persist it
// Note: product uses group, so group object has to be
// created first, but can be persisted later
productOql.bind( 4 );
results = productOql.execute();
if ( ! results.hasMore() )
{
product = new Product();
product.setId( 4 );
product.setName( "product4" );
product.setPrice( 200 );
product.setGroup( group );
detail = new ProductDetail();
detail.setId( 1 );
detail.setName( "keyboard" );
product.addDetail( detail );
detail = new ProductDetail();
detail.setId( 2 );
detail.setName( "mouse" );
product.addDetail( detail );
detail = new ProductDetail();
detail.setId( 3 );
detail.setName( "monitor" );
product.addDetail( detail );
LOG.debug( "Creating new product: " + product );
db.create( product );
}
else
{
LOG.debug( "Query result: " + results.next() );
}
// If no such computer exists in the database, create a new
// object and persist it
// Note: computer uses group, so group object has to be
// created first, but can be persisted later
computerOql.bind( 44 );
results = computerOql.execute();
if ( ! results.hasMore() ) {
computer = new Computer();
computer.setId( 44 );
computer.setCpu( "Pentium" );
computer.setName( "MyPC" );
computer.setPrice( 400 );
computer.setGroup( group );
detail = new ProductDetail();
detail.setId( 4 );
detail.setName( "network card" );
computer.addDetail( detail );
detail = new ProductDetail();
detail.setId( 5 );
detail.setName( "scsi card" );
computer.addDetail( detail );
LOG.debug( "Creating new computer: " + computer );
db.create( computer );
} else {
LOG.debug( "Query result: " + results.next() );
}
LOG.info( "End transaction: one-to-one, one-to-many and dependent relations" );
db.commit();
// Many-to-many example using one existing product
db.begin();
LOG.info( "Begin transaction: one-to-one and dependent relations" );
// If no such products with ids 5-8 exist, create new
// objects and persist them
for ( int i = 5; i < 10; ++i )
{
int j = i + 1;
productOql.bind( j );
results = productOql.execute();
if ( ! results.hasMore() )
{
product = new Product();
product.setId( i );
product.setName( "product" + product.getId() );
product.setPrice( 300 );
product.setGroup( group );
detail = new ProductDetail();
detail.setId( j );
detail.setName( "detail" + detail.getId() );
product.addDetail( detail );
LOG.debug( "Creating new product: " + product );
db.create( product );
}
else
{
LOG.debug( "Query result: " + results.next() );
}
}
LOG.info( "End transaction: one-to-one and dependent relations " );
db.commit();
db.begin();
LOG.info( "Begin transaction: many-to-many relations" );
for ( int x = 4; x < 7; ++x )
{
int y = x + 3;
product = ( Product ) db.load( Product.class, new Integer( y ) );
// If no such categories exists in the database, create new
// objects and persist them
categoryOql.bind( x );
results = categoryOql.execute();
if ( ! results.hasMore() )
{
category = new Category();
category.setId( x );
category.setName( "category" + category.getId() );
category.addProduct( product );
db.create( category );
LOG.debug( "Creating new category: " + category );
}
else
{
category = ( Category ) results.next();
LOG.debug( "Query result: " + category );
}
}
LOG.info( "End transaction: many-to-many relations" );
db.commit();
product.setPrice( 333 );
LOG.info( "Updated Product price: " + product );
db.begin();
LOG.info( "Begin transaction: long transaction" );
//
// Don't forget to implement TimeStampable for the long transaction!!!
//
db.update( product );
LOG.info( "End transaction: long transaction" );
db.commit();
db.begin();
LOG.info( "Begin transaction: update extends relation in long transaction " );
computerOql.bind( 44 );
results = computerOql.execute();
while ( results.hasMore() )
{
computer = new Computer();
computer = ( Computer ) results.next();
LOG.debug( "Found existing computer: " + computer );
}
LOG.info( "End transaction: update extends relation in long transaction" );
db.commit();
computer.setPrice( 425 );
LOG.info( "Updated Computer price: " + product );
db.begin();
LOG.info( "Begin transaction: update extends relation in long transaction " );
//
// Don't forget to implement TimeStampable for the long transaction!!!
//
db.update( computer );
LOG.info( "End transaction: update extends relation in long transaction" );
db.commit();
db.begin();
LOG.info( "Begin transaction: simple load and update within the same transaction" );
computerOql.bind( 44 );
results = computerOql.execute();
if ( results.hasMore() )
{
computer = ( Computer ) results.next();
computer.setCpu( "Opteron" );
}
LOG.info( "End transaction: simple load and update within the same transaction" );
db.commit();
db.begin();
LOG.info( "Begin transaction: simple load to test the previous change" );
computerOql.bind( 44 );
results = computerOql.execute();
if ( results.hasMore() )
{
LOG.info( "Loaded computer:" + results.next() );
}
LOG.info( "End transaction: simple load to test the previous change" );
db.commit();
Marshaller marshaller;
marshaller = new Marshaller( new PrintWriter(System.out) );
marshaller.setMapping( _mapping );
db.begin();
LOG.info( "Begin transaction: marshalling objects to XML" );
computerOql = db.getOQLQuery( "SELECT c FROM myapp.Computer c WHERE c.id >= $1" );
computerOql.bind( 10 );
results = computerOql.execute();
while( results.hasMore() )
marshaller.marshal( results.next() );
LOG.info( "End transaction: marshalling objects to XML" );
db.commit();
db.close();
LOG.info( "Test complete" );
// --------------------------------------------------------------------
LOG.info( "Begin: Walking the mapping descriptor via objects" );
MappingRoot mappingRoot = _mapping.getRoot();
ClassMapping classMap;
FieldMapping fieldMap;
FieldMapping[] fieldMaps;
int mappingCount = mappingRoot.getClassMappingCount();
// loop over the classes
for ( int i = 0; i < mappingCount; ++i )
{
classMap = mappingRoot.getClassMapping( i );
LOG.debug( "Class name: " + classMap.getName() );
fieldMaps = classMap.getClassChoice().getFieldMapping();
LOG.debug( "fieldMaps.length: " + fieldMaps.length );
// loop over the fields in each class
for ( int j = 0; j < fieldMaps.length; ++j )
{
fieldMap = fieldMaps[j];
LOG.debug( " Field name: " + fieldMap.getName() );
LOG.debug( " Field type: " + fieldMap.getType() );
}
}
LOG.info( "End: Walking the mapping descriptor via objects" );
// --------------------------------------------------------------------
}
}