List:Commits« Previous MessageNext Message »
From:Jonas Oreland Date:March 12 2010 3:03pm
Subject:bzr commit into mysql-5.1-telco-7.1 branch (jonas:3495)
View as plain text  
#At file:///home/jonas/src/telco-7.1/ based on revid:jonas@stripped

 3495 Jonas Oreland	2010-03-12 [merge]
      merge 71-main

    modified:
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/DomainFieldHandlerImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/AndPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/BetweenPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/InPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/NotPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/OrPredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryExecutionContextImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanFilter.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanOperation.java
      storage/ndb/clusterj/clusterj-core/src/main/resources/com/mysql/clusterj/core/Bundle.properties
      storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAConfiguration.java
      storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAConfigurationImpl.java
      storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainFieldHandlerImpl.java
      storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainTypeHandlerImpl.java
      storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAResult.java
      storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAStoreManager.java
      storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAStoreQuery.java
      storage/ndb/clusterj/clusterj-openjpa/src/main/resources/com/mysql/clusterj/openjpa/Bundle.properties
      storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryInTest.java
      storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/TimestampAsUtilDateTypesTest.java
      storage/ndb/clusterj/clusterj-tie/pom.xml
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DictionaryImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanFilterImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/TableImpl.java
      storage/ndb/src/ndbjtie/jtie/test/myapi/Makefile.am
      storage/ndb/src/ndbjtie/jtie/test/myjapi/Makefile.am
      storage/ndb/src/ndbjtie/utils/mystdint.h
=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/DomainFieldHandlerImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/DomainFieldHandlerImpl.java	2010-01-22 19:10:41 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/DomainFieldHandlerImpl.java	2010-03-12 09:31:36 +0000
@@ -132,6 +132,10 @@ public class DomainFieldHandlerImpl exte
                             + " is " + columnDefaultValue);
             }
             storeColumn = table.getColumn(columnName);
+            if (storeColumn == null) {
+                throw new ClusterJUserException(local.message("ERR_No_Column",
+                        name, table.getName(), columnName));
+            }
             storeColumnType = storeColumn.getType();
             charsetName = storeColumn.getCharsetName();
             if (logger.isDebugEnabled())

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/AndPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/AndPredicateImpl.java	2010-01-26 10:46:42 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/AndPredicateImpl.java	2010-03-12 09:31:36 +0000
@@ -91,7 +91,7 @@ public class AndPredicateImpl extends Pr
     public void filterCmpValue(QueryExecutionContextImpl context,
             ScanOperation op) {
         try {
-            ScanFilter filter = op.getScanFilter();
+            ScanFilter filter = op.getScanFilter(context);
             filter.begin(ScanFilter.Group.GROUP_AND);
             for (PredicateImpl predicate: predicates) {
                 predicate.filterCmpValue(context, op, filter);

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/BetweenPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/BetweenPredicateImpl.java	2010-01-26 10:46:42 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/BetweenPredicateImpl.java	2010-03-12 09:31:36 +0000
@@ -122,7 +122,7 @@ public class BetweenPredicateImpl extend
     public void filterCmpValue(QueryExecutionContextImpl context,
             ScanOperation op) {
         try {
-            ScanFilter filter = op.getScanFilter();
+            ScanFilter filter = op.getScanFilter(context);
             filter.begin();
             filterCmpValue(context, op, filter);
             filter.end();

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/InPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/InPredicateImpl.java	2010-01-26 10:46:42 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/InPredicateImpl.java	2010-03-12 09:31:36 +0000
@@ -63,7 +63,7 @@ public class InPredicateImpl extends Pre
     public void filterCmpValue(QueryExecutionContextImpl context,
             ScanOperation op) {
         try {
-            ScanFilter filter = op.getScanFilter();
+            ScanFilter filter = op.getScanFilter(context);
             filterCmpValue(context, op, filter);
         } catch (ClusterJException ex) {
             throw ex;

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/NotPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/NotPredicateImpl.java	2010-01-26 10:46:42 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/NotPredicateImpl.java	2010-03-12 09:31:36 +0000
@@ -56,7 +56,7 @@ public class NotPredicateImpl extends Pr
     public void filterCmpValue(QueryExecutionContextImpl context,
             ScanOperation op) {
         try {
-            ScanFilter filter = op.getScanFilter();
+            ScanFilter filter = op.getScanFilter(context);
             filter.begin(Group.GROUP_NAND);
             predicate.filterCmpValue(context, op, filter);
             filter.end();

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/OrPredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/OrPredicateImpl.java	2010-01-26 10:46:42 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/OrPredicateImpl.java	2010-03-12 09:31:36 +0000
@@ -89,7 +89,7 @@ public class OrPredicateImpl extends Pre
     public void filterCmpValue(QueryExecutionContextImpl context,
             ScanOperation op) {
         try {
-            ScanFilter filter = op.getScanFilter();
+            ScanFilter filter = op.getScanFilter(context);
             filter.begin(Group.GROUP_OR);
             for (PredicateImpl predicate: predicates) {
                 predicate.filterCmpValue(context, op, filter);

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PredicateImpl.java	2010-03-01 06:59:49 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PredicateImpl.java	2010-03-12 09:31:36 +0000
@@ -134,7 +134,7 @@ public abstract class PredicateImpl impl
     public void filterCmpValue(QueryExecutionContextImpl context,
             ScanOperation op) {
         try {
-            ScanFilter filter = op.getScanFilter();
+            ScanFilter filter = op.getScanFilter(context);
             filter.begin();
             filterCmpValue(context, op, filter);
             filter.end();

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java	2010-03-01 06:59:49 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java	2010-03-12 09:31:36 +0000
@@ -207,6 +207,7 @@ public class QueryDomainTypeImpl<T> impl
         explain = new HashMap<String, Object>();
         explain.put("ScanType", scanType.toString());
         explain.put("IndexUsed", theIndexUsed);
+        ResultData result = null;
 
         switch (scanType) {
 
@@ -218,8 +219,8 @@ public class QueryDomainTypeImpl<T> impl
                 // set the expected columns into the operation
                 domainTypeHandler.operationGetValues(op);
                 // execute the select and get results
-                ResultData rs = op.resultData();
-                return rs;
+                result = op.resultData();
+                break;
             }
 
             case INDEX_SCAN: {
@@ -238,8 +239,8 @@ public class QueryDomainTypeImpl<T> impl
                 // set additional filter conditions
                 where.filterCmpValue(context, op);
                 // execute the scan and get results
-                ResultData rs = op.resultData();
-                return rs;
+                result = op.resultData();
+                break;
             }
 
             case TABLE_SCAN: {
@@ -253,8 +254,8 @@ public class QueryDomainTypeImpl<T> impl
                     where.filterCmpValue(context, op);
                 }
                 // execute the scan and get results
-                ResultData rs = op.resultData();
-                return rs;
+                result = op.resultData();
+                break;
             }
 
             case UNIQUE_SCAN: {
@@ -271,8 +272,8 @@ public class QueryDomainTypeImpl<T> impl
                 //domainTypeHandler.operationGetValuesExcept(op, indexName);
                 domainTypeHandler.operationGetValues(op);
                 // execute the select and get results
-                ResultData rs = op.resultData();
-                return rs;
+                result = op.resultData();
+                break;
             }
 
             default:
@@ -280,6 +281,8 @@ public class QueryDomainTypeImpl<T> impl
                 throw new ClusterJFatalInternalException(
                         local.message("ERR_Illegal_Scan_Type", scanType));
         }
+        context.deleteFilters();
+        return result;
     }
 
     protected CandidateIndexImpl[] createCandidateIndexes() {

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryExecutionContextImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryExecutionContextImpl.java	2010-01-22 19:10:41 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryExecutionContextImpl.java	2010-03-12 09:31:36 +0000
@@ -22,12 +22,15 @@ import com.mysql.clusterj.ClusterJFatalI
 import com.mysql.clusterj.ClusterJUserException;
 import com.mysql.clusterj.core.spi.SessionSPI;
 import com.mysql.clusterj.core.store.ResultData;
+import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.util.I18NHelper;
 import com.mysql.clusterj.core.util.Logger;
 import com.mysql.clusterj.core.util.LoggerFactoryService;
 import com.mysql.clusterj.query.QueryDomainType;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /** This is the execution context for a query. It contains the
@@ -48,6 +51,9 @@ public class QueryExecutionContextImpl {
     /** The session for this query */
     protected SessionSPI session;
 
+    /** The filters used in the query */
+    private List<ScanFilter> filters = new ArrayList<ScanFilter>();
+
     /** Create a new execution context with an empty map of parameters.
      * @param session the session for this context
      */
@@ -73,8 +79,8 @@ public class QueryExecutionContextImpl {
      * @param parameterMap the parameter map for this context
      */
     public QueryExecutionContextImpl(SessionSPI session, Map<String, Object> parameterMap) {
-	this.session = session;
-	this.boundParameters = parameterMap;
+        this.session = session;
+        this.boundParameters = parameterMap;
     }
 
     /** Bind the value of a parameter for this query execution.
@@ -109,10 +115,27 @@ public class QueryExecutionContextImpl {
     }
 
     public SessionSPI getSession() {
-	return session;
+        return session;
     }
 
     public ResultData getResultData(QueryDomainType<?> queryDomainType) {
-	return ((QueryDomainTypeImpl<?>)queryDomainType).getResultData(this);
+        return ((QueryDomainTypeImpl<?>)queryDomainType).getResultData(this);
+    }
+
+    /** Add a filter to the list of filters created for this query.
+     * @param scanFilter the filter
+     */
+    public void addFilter(ScanFilter scanFilter) {
+        filters.add(scanFilter);
     }
+
+    /** Delete all the filters created for this query.
+     */
+    public void deleteFilters() {
+        for (ScanFilter filter: filters) {
+            filter.delete();
+        }
+        filters.clear();
+    }
+
 }

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanFilter.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanFilter.java	2010-01-26 10:46:42 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanFilter.java	2010-03-12 09:31:36 +0000
@@ -59,5 +59,7 @@ public interface ScanFilter {
     public void end();
 
     public void isNull(Column storeColumn);
+    
+    public void delete();
 
 }

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanOperation.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanOperation.java	2010-01-22 19:10:41 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/ScanOperation.java	2010-03-12 09:31:36 +0000
@@ -18,6 +18,8 @@
 
 package com.mysql.clusterj.core.store;
 
+import com.mysql.clusterj.core.query.QueryExecutionContextImpl;
+
 /**
  *
  */
@@ -27,7 +29,7 @@ public interface ScanOperation extends O
 
     public void deleteCurrentTuple();
 
-    public ScanFilter getScanFilter();
+    public ScanFilter getScanFilter(QueryExecutionContextImpl context);
 
     public int nextResult(boolean fetch);
 

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/resources/com/mysql/clusterj/core/Bundle.properties'
--- a/storage/ndb/clusterj/clusterj-core/src/main/resources/com/mysql/clusterj/core/Bundle.properties	2010-01-26 10:46:42 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/resources/com/mysql/clusterj/core/Bundle.properties	2010-03-12 09:31:36 +0000
@@ -77,6 +77,7 @@ must not include the columns attribute.
 ERR_Index_Mismatch:For class {0}, index {1}, column {2} has no corresponding field.
 ERR_Duplicate_Index:For class {0}, index {1} is duplicated.
 ERR_Duplicate_Column:For class {0}, index {1}, column {2} is duplicated.
+ERR_No_Column:For field {0}, table {1} does not define column {2}.
 ERR_Wrong_Domain_Object:For operation {0}, domain objects must be identical.
 ERR_Implementation_Should_Not_Occur:Error in implementation. Please file \
 an issue.

=== modified file 'storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAConfiguration.java'
--- a/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAConfiguration.java	2010-01-22 16:07:59 +0000
+++ b/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAConfiguration.java	2010-03-12 09:31:36 +0000
@@ -88,5 +88,9 @@ public interface NdbOpenJPAConfiguration
     public SessionFactory getSessionFactory();
     public void setSessionFactory(SessionFactory value);
 
+    public boolean getFailOnJDBCPath();
+    public void setFailOnJDBCPath(boolean value);
+
     public NdbOpenJPADomainTypeHandlerImpl<?> getDomainTypeHandler(ClassMapping cmd, Dictionary dictionary);
+
 }

=== modified file 'storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAConfigurationImpl.java'
--- a/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAConfigurationImpl.java	2010-01-22 16:07:59 +0000
+++ b/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAConfigurationImpl.java	2010-03-12 09:31:36 +0000
@@ -31,12 +31,14 @@ import com.mysql.clusterj.core.util.I18N
 import com.mysql.clusterj.core.util.Logger;
 import com.mysql.clusterj.core.util.LoggerFactoryService;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
 
 import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
 import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.lib.conf.BooleanValue;
 import org.apache.openjpa.lib.conf.IntValue;
 import org.apache.openjpa.lib.conf.ProductDerivations;
 import org.apache.openjpa.lib.conf.StringValue;
@@ -66,6 +68,7 @@ public class NdbOpenJPAConfigurationImpl
     public StringValue password;
     public StringValue database;
     public IntValue maxTransactions;
+    public BooleanValue failOnJDBCPath;
     public SessionFactoryImpl sessionFactory;
     private final Map<Class<?>, NdbOpenJPADomainTypeHandlerImpl<?>> domainTypeHandlerMap =
             new HashMap<Class<?>, NdbOpenJPADomainTypeHandlerImpl<?>>();
@@ -112,6 +115,8 @@ public class NdbOpenJPAConfigurationImpl
         database.set("test");
         maxTransactions = addInt("ndb.maxTransactions");
         maxTransactions.set(1024);
+        failOnJDBCPath = addBoolean("ndb.failOnJDBCPath");
+        failOnJDBCPath.set(false);
 
         sessionFactory = null;
 
@@ -210,6 +215,14 @@ public class NdbOpenJPAConfigurationImpl
         maxTransactions.set(value);
     }
 
+    public boolean getFailOnJDBCPath() {
+        return failOnJDBCPath.get();
+    }
+
+    public void setFailOnJDBCPath(boolean value) {
+        failOnJDBCPath.set(value);
+    }
+
     public SessionFactoryImpl getSessionFactory() {
         if (sessionFactory == null) {
             sessionFactory = createSessionFactory();
@@ -263,8 +276,13 @@ public class NdbOpenJPAConfigurationImpl
         synchronized(domainTypeHandlerMap) {
             result = domainTypeHandlerMap.get(domainClass);
             if (result == null) {
+                if (logger.isDebugEnabled()) logger.debug("domain class: " + domainClass.getName());
                 result = createDomainTypeHandler(cmd, dictionary);
                 domainTypeHandlerMap.put(domainClass, result);
+                result.initializeRelations();
+                logger.info("New domain type " + result.getName()
+                        + (result.isSupportedType()?" is supported.":
+                            " is not known to be supported because " + result.getReasons()));
             }
         }
         return result;

=== modified file 'storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainFieldHandlerImpl.java'
--- a/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainFieldHandlerImpl.java	2010-03-01 06:59:49 +0000
+++ b/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainFieldHandlerImpl.java	2010-03-12 09:31:36 +0000
@@ -19,12 +19,12 @@
 package com.mysql.clusterj.openjpa;
 
 import com.mysql.clusterj.ClusterJFatalInternalException;
-import com.mysql.clusterj.ClusterJFatalUserException;
 import com.mysql.clusterj.ClusterJUserException;
 
 import com.mysql.clusterj.core.metadata.AbstractDomainFieldHandlerImpl;
 import com.mysql.clusterj.core.query.QueryDomainTypeImpl;
 import com.mysql.clusterj.core.spi.DomainTypeHandler;
+import com.mysql.clusterj.core.spi.SessionSPI;
 import com.mysql.clusterj.core.spi.ValueHandler;
 import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.IndexScanOperation.BoundType;
@@ -33,6 +33,7 @@ import com.mysql.clusterj.core.store.Ope
 import com.mysql.clusterj.core.store.PartitionKey;
 import com.mysql.clusterj.core.store.ResultData;
 import com.mysql.clusterj.core.store.ScanFilter;
+import com.mysql.clusterj.core.store.Table;
 import com.mysql.clusterj.core.store.ScanFilter.BinaryCondition;
 import com.mysql.clusterj.core.util.I18NHelper;
 import com.mysql.clusterj.core.util.Logger;
@@ -78,9 +79,6 @@ public class NdbOpenJPADomainFieldHandle
     /** My logger */
     static final Logger logger = LoggerFactoryService.getFactory().getInstance(NdbOpenJPADomainFieldHandlerImpl.class);
 
-    /** The domain type handler factory */
-    NdbOpenJPAConfigurationImpl domainTypeHandlerFactory = null;
-
     private static com.mysql.clusterj.core.store.Column[] emptyStoreColumns = new com.mysql.clusterj.core.store.Column[] {};
     /** The openjpa field mapping for this field */
     private FieldMapping fieldMapping;
@@ -124,14 +122,22 @@ public class NdbOpenJPADomainFieldHandle
     /** The name of the related field */
     private String relatedFieldName;
 
+    /** If this field is supported for clusterjpa */
+    private boolean supported = true;
+
+    /** The reason the field is not supported */
+    private String reason = "";
+
+    private RelatedFieldLoadManager relatedFieldLoadManager;
+
     public FieldMapping getFieldMapping() {
         return fieldMapping;
     }
 
     public NdbOpenJPADomainFieldHandlerImpl(Dictionary dictionary, NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler,
-            NdbOpenJPAConfigurationImpl domainTypeHandlerFactory, FieldMapping fieldMapping) {
+            NdbOpenJPAConfigurationImpl domainTypeHandlerFactory, final FieldMapping fieldMapping) {
 
-        this.domainTypeHandlerFactory = domainTypeHandlerFactory;
+        String message = null;
         this.fieldMapping = fieldMapping;
         this.domainTypeHandler = domainTypeHandler;
         this.name = fieldMapping.getName();
@@ -144,11 +150,11 @@ public class NdbOpenJPADomainFieldHandle
         this.isToOne = fieldMapping.getStrategy() instanceof RelationFieldStrategy;
         if (isMappedBy) {
             relatedType = mappedByMapping.getDeclaringType();
+            relatedFieldMapping = fieldMapping.getMappedByMapping();
         }
         // TODO are these valid for every field?
         this.relatedTypeMapping = fieldMapping.getDeclaredTypeMapping();
         if (relatedTypeMapping != null) {
-            relatedFieldMapping = fieldMapping.getMappedByMapping();
             relatedType = relatedTypeMapping.getDescribedType();
         }
         if (relatedType != null) {
@@ -164,7 +170,13 @@ public class NdbOpenJPADomainFieldHandle
                 // each field is mapped to one column
                 this.column = columns[0];
                 this.columnName = column.getName();
-                this.storeColumn = domainTypeHandler.getTable().getColumn(columnName);
+                Table table = domainTypeHandler.getTable();
+                this.storeColumn = table.getColumn(columnName);
+                if (storeColumn == null) {
+                    message = local.message("ERR_No_Column", name, table.getName(), columnName);
+                    setUnsupported(message);
+                    return;
+                }
                 this.storeColumns = new com.mysql.clusterj.core.store.Column[] {storeColumn};
                 charsetName = storeColumn.getCharsetName();
                 // set up the default object operation handler for the column type
@@ -172,12 +184,14 @@ public class NdbOpenJPADomainFieldHandle
                 this.javaType = column.getJavaType();
                 this.objectOperationHandlerDelegate = getObjectOperationHandler(javaType);
                 if (objectOperationHandlerUnsupportedType.equals(objectOperationHandlerDelegate)) {
-                    throw new ClusterJFatalUserException(
-                            local.message("ERR_Unsupported_Meta_Type", javaType));
-                }
-                this.javaTypeName = NdbOpenJPAUtility.getJavaTypeName(javaType);
-                if (storeColumn.isPrimaryKey()) {
-                    domainTypeHandler.registerPrimaryKeyColumn(this, storeColumn.getName());
+                    message = local.message("ERR_Unsupported_Meta_Type", javaType);
+                    setUnsupported(message);
+                    return;
+                } else {
+                    this.javaTypeName = NdbOpenJPAUtility.getJavaTypeName(javaType);
+                    if (storeColumn.isPrimaryKey()) {
+                        domainTypeHandler.registerPrimaryKeyColumn(this, storeColumn.getName());
+                    }
                 }
             } else if (columns.length > 1) {
                 // error, no support
@@ -188,34 +202,40 @@ public class NdbOpenJPADomainFieldHandle
                     buffer.append(errorColumn.getName());
                     separator = ", ";
                 }
-                String message = local.message("ERR_More_Than_One_Column_Mapped_To_A_Field",
+                message = local.message("ERR_More_Than_One_Column_Mapped_To_A_Field",
                         domainTypeHandler.getName(), name, buffer);
-                logger.error(message);
-                throw new ClusterJFatalUserException(message);
+                logger.info(message);
+                setUnsupported(message);
+                return;
             } else if (columns.length == 0) {
-                String message = local.message("ERR_No_Column_Mapped_To_A_Field",
+                message = local.message("ERR_No_Column_Mapped_To_A_Field",
                         domainTypeHandler.getName(), name, fieldMapping.getTable(), fieldMapping.getStrategy().getClass().getName());
                 logger.info(message);
-                throw new ClusterJFatalUserException(message);
+                setUnsupported(message);
+                return;
             }
             if (this.primaryKey) {
                 // each field is mapped to its own column
                 // if using a user-defined openJPAId class, set up the value handler
-                oidField = getFieldForOidClass(domainTypeHandler.getOidClass(), name);
+                oidField = getFieldForOidClass(this, domainTypeHandler.getOidClass(), name);
                 indexNames.add("PRIMARY");
                 switch (javaType) {
-                    case JavaTypes.INT: this.objectOperationHandlerDelegate =
-                            objectOperationHandlerKeyInt;
+                    case JavaTypes.INT: 
+                    case JavaTypes.INT_OBJ: 
+                        this.objectOperationHandlerDelegate = objectOperationHandlerKeyInt;
                         break;
-                    case JavaTypes.LONG: this.objectOperationHandlerDelegate =
-                            objectOperationHandlerKeyLong;
+                    case JavaTypes.LONG:
+                    case JavaTypes.LONG_OBJ: 
+                        this.objectOperationHandlerDelegate = objectOperationHandlerKeyLong;
                         break;
-                    case JavaTypes.STRING: this.objectOperationHandlerDelegate =
-                            objectOperationHandlerKeyString;
+                   case JavaTypes.STRING: this.objectOperationHandlerDelegate =
+                        objectOperationHandlerKeyString;
                         break;
-                    default: throw new ClusterJFatalUserException(
-                            local.message("ERR_Illegal_Foreign_Key_Type",
-                            domainTypeHandler.getName(), name, javaTypeName));
+                    default: 
+                        message = local.message("ERR_Illegal_Primary_Key_Type",
+                            domainTypeHandler.getName(), name, columnName, javaTypeName);
+                        logger.info(message);
+                        setUnsupported(message);
                 }
             }
         } else if (isRelation) {
@@ -224,19 +244,31 @@ public class NdbOpenJPADomainFieldHandle
                 this.column = columns[0];
                 this.columnName = column.getName();
                 this.columnNames = new String[] {columnName};
-                this.storeColumn = domainTypeHandler.getTable().getColumn(columnName);
+                Table table = domainTypeHandler.getTable();
+                this.storeColumn = table.getColumn(columnName);
+                if (storeColumn == null) {
+                    message = local.message("ERR_No_Column", name, table.getName(), columnName);
+                    setUnsupported(message);
+                    return;
+                }
                 this.storeColumns = new com.mysql.clusterj.core.store.Column[] {storeColumn};
                 // set up the default object operation handler for the column type
                 this.javaType = column.getJavaType();
                 this.javaTypeName = NdbOpenJPAUtility.getJavaTypeName(javaType);
                 this.objectOperationHandlerDelegate = getObjectOperationHandlerRelationDelegate(javaType);
+                if (objectOperationHandlerDelegate == null) {
+                    // unsupported primary key type
+                    return;
+                }
             } else if (columns.length == 0) {
                 if (isMappedBy) {
                     // this is the case of a OneToMany field mapped by columns in another table
                     this.objectOperationHandlerDelegate = objectOperationHandlerVirtualType;
                 } else {
-                    throw new ClusterJUserException(local.message("ERR_No_Columns_And_Not_Mapped_By",
-                            this.domainTypeHandler.getName(), this.name));
+                    message = local.message("ERR_No_Columns_And_Not_Mapped_By",
+                            this.domainTypeHandler.getName(), this.name);
+                    logger.info(message);
+                    setUnsupported(message);
                 }
             } else {
                 // multiple columns for related object
@@ -261,23 +293,38 @@ public class NdbOpenJPADomainFieldHandle
                     this.columnNames = new String[columns.length];
                     this.storeColumns = new com.mysql.clusterj.core.store.Column[columns.length];
                     for (int i = 0; i < columns.length; ++i) {
-                        StringBuffer message = new StringBuffer();
+                        StringBuffer detailMessage = new StringBuffer();
                         Column localColumn = columns[i];
                         String localColumnName = localColumn.getName();
-                        com.mysql.clusterj.core.store.Column localStoreColumn = domainTypeHandler.getTable().getColumn(localColumnName);
+                        Table table = domainTypeHandler.getTable();
+                        com.mysql.clusterj.core.store.Column localStoreColumn = table.getColumn(localColumnName);
+                        if (localStoreColumn == null) {
+                            message = local.message("ERR_No_Column", name, table.getName(), localColumnName);
+                            logger.info(message);
+                            setUnsupported(message);
+                            return;
+                        }
                         this.storeColumns[i] = localStoreColumn;
                         this.columnNames[i] = localColumnName;
                         ForeignKey foreignKey = fieldMapping.getForeignKey();
                         // get the primary key column corresponding to the local column
                         Column pkColumn = foreignKey.getPrimaryKeyColumn(localColumn);
                         if (logger.isDetailEnabled()) {
-                            message.append(" column: " + localColumnName);
-                            message.append(" fk-> " + foreignKey);
-                            message.append(" pkColumn-> " + pkColumn);
-                            logger.detail(message.toString());
+                            detailMessage.append(" column: " + localColumnName);
+                            detailMessage.append(" fk-> " + foreignKey);
+                            detailMessage.append(" pkColumn-> " + pkColumn);
+                            logger.detail(detailMessage.toString());
+                        }
+                        NdbOpenJPADomainFieldHandlerImpl relatedFieldHandler = 
+                            new NdbOpenJPADomainFieldHandlerImpl(this, localColumn, pkColumn);
+                        if (relatedFieldHandler.isSupported()) {
+                            this.compositeDomainFieldHandlers[i] = relatedFieldHandler;
+                        } else {
+                            message = relatedFieldHandler.getReason();
+                            setUnsupported(message);
+                            return;
                         }
-                        this.compositeDomainFieldHandlers[i] =
-                                new NdbOpenJPADomainFieldHandlerImpl(this, localColumn, pkColumn);
+                                
                     }
                     this.objectOperationHandlerDelegate =
                             objectOperationHandlerRelationCompositeField;
@@ -285,23 +332,31 @@ public class NdbOpenJPADomainFieldHandle
             }
         } else {
             // embedded field
-            throw new ClusterJUserException(local.message("ERR_Embedded_Fields_Not_Supported",
-                    this.domainTypeHandler.getName(), this.name));
+            message = local.message("ERR_Embedded_Fields_Not_Supported",
+                    this.domainTypeHandler.getName(), this.name);
+            logger.info(message);
+            setUnsupported(message);
+            return;
         }
-        // now handle indexes
+        // now handle indexes, for supported field types
         Index index = fieldMapping.getJoinIndex();
         // TODO: where is this annotation used?
         if (index != null) {
-            StringBuffer buffer = null;
-            if (logger.isDetailEnabled())  buffer = new StringBuffer("Found index name ");
             String indexName = index.getName();
-            if (logger.isDetailEnabled())  buffer.append(indexName); buffer.append(" [");
             Column[] indexColumns = index.getColumns();
-            for (Column indexColumn : indexColumns) {
-                if (logger.isDetailEnabled()) buffer.append(indexColumn.getName()); buffer.append(" ");
+            if (logger.isDetailEnabled()) {
+                StringBuilder buffer = new StringBuilder("Found index name ");
+                buffer.append(indexName);
+                buffer.append(" [");
+                for (Column indexColumn : indexColumns) {
+                    if (logger.isDetailEnabled()) {
+                        buffer.append(indexColumn.getName());
+                        buffer.append(" ");
+                    }
+                }
+                buffer.append("]");
+                logger.detail(buffer.toString());
             }
-            if (logger.isDetailEnabled()) buffer.append("]");
-            if (logger.isDetailEnabled()) logger.detail(buffer.toString());
         }
         index = fieldMapping.getValueIndex();
         // Value indexes are used for ManyToOne and OneToOne relationship indexes on the mapped side
@@ -332,6 +387,95 @@ public class NdbOpenJPADomainFieldHandle
         }
     }
 
+    /** Initialize relationship handling. There are three types of relationships
+     * supported by clusterjpa:
+     * <ul><li>direct ToOne relationship mapped by a foreign key on this side
+     * </li><li>ToOne relationship mapped by a foreign key on the other side
+     * </li><li>ToMany relationship mapped by a foreign key on the other side
+     * </li></ul>
+     * 
+     */
+    public void initializeRelations() {
+        if (isRelation) {
+            // set up related field load handler
+            if (isMappedBy && isToOne) {
+                // mapped by other side with one instance
+                this.relatedDomainTypeHandler = ((NdbOpenJPADomainTypeHandlerImpl<?>)domainTypeHandler)
+                        .registerDependency(relatedTypeMapping);
+                this.relatedFieldName = relatedFieldMapping.getName();
+                relatedFieldLoadManager = new RelatedFieldLoadManager() {
+                    public void load(OpenJPAStateManager sm, NdbOpenJPAStoreManager store, 
+                            JDBCFetchConfiguration fetch) throws SQLException {
+                        SessionSPI session = store.getSession();
+                        session.startAutoTransaction();
+                        NdbOpenJPAResult queryResult = queryRelated(sm, store);
+                        Object related = null;
+                        try {
+                            if (queryResult.next()) {
+                                // instantiate the related object from the result of the query
+                                related = store.load(relatedTypeMapping, fetch, (BitSet) null, queryResult);
+                            }
+                            if (logger.isDetailEnabled()) logger.detail("related object is: " + related);
+                            // store the value of the related object in this field
+                            sm.storeObjectField(fieldNumber, related);
+                            session.endAutoTransaction();
+                        } catch (Exception e) {
+                            session.failAutoTransaction();
+                        }
+                    }
+                };
+                if (logger.isDetailEnabled()) logger.detail("Single-valued relationship field " + name
+                        + " is mapped by " + relatedTypeName + " field " + relatedFieldName
+                        + " with relatedDomainTypeHandler " + relatedDomainTypeHandler.getName());
+            } else if (isMappedBy && !isToOne) {
+                // mapped by other side with multiple instances
+                this.relatedTypeMapping = mappedByMapping.getDeclaringMapping();
+                this.relatedDomainTypeHandler = ((NdbOpenJPADomainTypeHandlerImpl<?>)domainTypeHandler)
+                        .registerDependency(relatedTypeMapping);
+                this.relatedFieldName = mappedByMapping.getName();
+                relatedTypeName = relatedDomainTypeHandler.getName();
+                if (logger.isDetailEnabled()) logger.detail("Multi-valued relationship field " + name
+                        + " is mapped by " + relatedTypeName + " field " + relatedFieldName);
+                    relatedFieldLoadManager = new RelatedFieldLoadManager() {
+                        public void load(OpenJPAStateManager sm, NdbOpenJPAStoreManager store, 
+                                JDBCFetchConfiguration fetch) throws SQLException {
+                            SessionSPI session = store.getSession();
+                            session.startAutoTransaction();
+                            try {
+                                NdbOpenJPAResult queryResult = queryRelated(sm, store);
+                                while (queryResult.next()) {
+                                    store.load(relatedTypeMapping, fetch, (BitSet) null, queryResult);
+                                }
+                                fieldMapping.load(sm, store, fetch);
+                                session.endAutoTransaction();
+                            } catch (Exception e) {
+                                session.failAutoTransaction();
+                            }
+                    }
+                };
+            } else {
+                // this side contains foreign key to other side
+                if (logger.isDetailEnabled()) logger.detail("NdbOpenJPADomainFieldHandlerImpl.initializeRelations for " 
+                        + fieldMapping.getName() + " column " + (column==null?"null":column.getName())
+                        + " relatedFieldName " + relatedFieldName
+                        + " relatedFieldMapping " + relatedFieldMapping
+                        + " relatedTypeMapping " + relatedTypeMapping);
+                // record dependency to related type if not null
+                if (relatedTypeMapping != null) {
+                    this.relatedDomainTypeHandler = ((NdbOpenJPADomainTypeHandlerImpl<?>)domainTypeHandler)
+                        .registerDependency(relatedTypeMapping);
+                    relatedFieldLoadManager = new RelatedFieldLoadManager() {
+                        public void load(OpenJPAStateManager sm, NdbOpenJPAStoreManager store, 
+                                JDBCFetchConfiguration fetch) throws SQLException {
+                            if (logger.isDetailEnabled()) logger.detail("Loading field " + name + "from stored key");
+                            fieldMapping.load(sm, store, fetch);
+                        }
+                    };
+                }
+            }
+        }
+    }
+
     /** Get the object operation handler for the specific java field type.
      * @param javaType the java type from JavaTypes or JavaSQLTypes
      * @return the object operation handler
@@ -386,11 +530,23 @@ public class NdbOpenJPADomainFieldHandle
      */
     public NdbOpenJPADomainFieldHandlerImpl(NdbOpenJPADomainFieldHandlerImpl parent,
             Column localColumn, Column pkColumn) {
+        String message = null;
         if (logger.isDetailEnabled()) logger.detail("NdbOpenJPADomainFieldHandlerImpl<init> for localColumn: " + localColumn + " pkColumn: " + pkColumn);
         this.column = localColumn;
-        this.storeColumn = parent.domainTypeHandler.getStoreTable().getColumn(localColumn.getName());
+        Table table = parent.domainTypeHandler.getStoreTable();
+        this.storeColumn = table.getColumn(localColumn.getName());
+        if (storeColumn == null) {
+            message = local.message("ERR_No_Column", parent.getName(), table.getName(), columnName);
+            setUnsupported(message);
+            logger.info(message);
+            return;
+        }
         this.javaType = column.getJavaType();
         this.objectOperationHandlerDelegate = getObjectOperationHandlerRelationDelegate(javaType);
+        if (objectOperationHandlerDelegate == null) {
+            // unsupported primary key type
+            return;
+        }
         this.columnName = column.getName();
         this.fieldNumber = parent.fieldNumber;
         this.domainTypeHandler = parent.domainTypeHandler;
@@ -409,14 +565,16 @@ public class NdbOpenJPADomainFieldHandle
             if (rcs.length == 1 && rcs[0].equals(pkColumn)) {
                 // found the corresponding pk field
                 String pkFieldName = rfm.getName();
-                oidField = getFieldForOidClass(relatedTypeMapping.getObjectIdType(), pkFieldName);
+                oidField = getFieldForOidClass(this, relatedTypeMapping.getObjectIdType(), pkFieldName);
             if (logger.isDetailEnabled()) logger.detail("NdbOpenJPADomainFieldHandlerImpl<init> found primary key column: " + rcs[0] + " for field: " + pkFieldName);
                 break;
             }
         }
         if (oidField == null) {
-            throw new ClusterJUserException(
-                    local.message("ERR_No_Oid_Field", pkColumn));
+            message = local.message("ERR_No_Oid_Field", pkColumn);
+            setUnsupported(message);
+            logger.info(message);
+            return;
         }
         if (logger.isTraceEnabled()) {
             logger.trace(" Relation Field Handler for column: " + columnName +
@@ -429,6 +587,11 @@ public class NdbOpenJPADomainFieldHandle
 
     }
 
+    interface RelatedFieldLoadManager {
+        public void load(OpenJPAStateManager sm, NdbOpenJPAStoreManager store, 
+                JDBCFetchConfiguration fetch) throws SQLException ;
+    }
+
     /** Load the value of this field. This will be done here only for relationship fields,
      * since basic fields are loaded when the instance is first initialized.
      *  
@@ -439,41 +602,11 @@ public class NdbOpenJPADomainFieldHandle
      */
     public void load(OpenJPAStateManager sm, NdbOpenJPAStoreManager store, JDBCFetchConfiguration fetch)
             throws SQLException {
-        // TODO: move initialization of relatedDomainTypeHandler etc. to a new post-create method.
-        if (isMappedBy && isToOne) {
-            // for single-valued fields, query for the object whose foreign key matches this primary key
-            this.relatedDomainTypeHandler = domainTypeHandlerFactory.getDomainTypeHandler(relatedTypeMapping, store.getDictionary());
-            this.relatedFieldName = relatedFieldMapping.getName();
-            if (logger.isDetailEnabled()) logger.detail("Single-valued relationship field " + name + " is mapped by " + relatedTypeName + " field " + relatedFieldName + " with relatedDomainTypeHandler " + relatedDomainTypeHandler.getName());
-            NdbOpenJPAResult queryResult = queryRelated(sm, store);
-            Object related = null;
-            if (queryResult.next()) {
-                // instantiate the related object from the result of the query
-                related = store.load(relatedTypeMapping, fetch, (BitSet) null, queryResult);
-            }
-            if (logger.isDetailEnabled()) logger.detail("related object is: " + related);
-            // store the value of the related object in this field
-            sm.storeObjectField(fieldNumber, related);
-        } else if (isMappedBy && !isToOne) {
-            // for multi-valued fields, query for the objects whose foreign key matches this primary key
-            this.relatedTypeMapping = mappedByMapping.getDeclaringMapping();
-            this.relatedDomainTypeHandler = domainTypeHandlerFactory.getDomainTypeHandler(relatedTypeMapping, store.getDictionary());
-            this.relatedFieldName = mappedByMapping.getName();
-            relatedTypeName = relatedDomainTypeHandler.getName();
-            if (logger.isDetailEnabled()) logger.detail("Multi-valued relationship field " + name + " is mapped by " + relatedTypeName + " field " + relatedFieldName);
-
-            NdbOpenJPAResult queryResult = queryRelated(sm, store);
-            while (queryResult.next()) {
-                store.load(relatedTypeMapping, fetch, (BitSet) null, queryResult);
-            }
-            // during loading of the related instances (above), 
-           // the relationship was established to this field
-            fieldMapping.load(sm, store, fetch);
-        } else {
-            // this field already contains the primary key of the other side
-            if (logger.isDetailEnabled()) logger.detail("Loading field " + name + "from stored key");
-            fieldMapping.load(sm, store, fetch);
+        if (!isRelation) {
+            throw new ClusterJFatalInternalException("load called for non-relationship field "
+                    + this.getName() + " mapped to column " + this.columnName);
         }
+        relatedFieldLoadManager.load(sm, store, fetch);
     }
 
     /** Query the related type for instance(s) whose related field refers to this instance.
@@ -492,6 +625,7 @@ public class NdbOpenJPADomainFieldHandle
         queryDomainType.where(predicate);
         Map<String, Object> parameterList = new HashMap<String, Object>();
         parameterList.put(relatedFieldName, thisOid);
+        if (logger.isDetailEnabled()) logger.detail(parameterList.toString());
         NdbOpenJPAResult queryResult = store.executeQuery(relatedDomainTypeHandler, queryDomainType, parameterList);
         // debug query result
         if (logger.isDetailEnabled()) {
@@ -527,7 +661,7 @@ public class NdbOpenJPADomainFieldHandle
 
     public ObjectOperationHandler[] objectOperationHandlers =
             new ObjectOperationHandler[] {
-        objectOperationHandlerUnsupportedType, /* 0: boolean */
+        objectOperationHandlerBoolean,         /* 0: boolean */
         objectOperationHandlerByte,            /* 1: byte */
         objectOperationHandlerUnsupportedType, /* 2: char */
         objectOperationHandlerDouble,          /* 3: double */
@@ -543,7 +677,7 @@ public class NdbOpenJPADomainFieldHandle
         objectOperationHandlerUnsupportedType, /* 13: Map */
         objectOperationHandlerJavaUtilDate,    /* 14: java.util.Date */
         objectOperationHandlerUnsupportedType, /* 15: PC */
-        objectOperationHandlerUnsupportedType, /* 16: Boolean */
+        objectOperationHandlerObjectBoolean,   /* 16: Boolean */
         objectOperationHandlerObjectByte,      /* 17: Byte */
         objectOperationHandlerUnsupportedType, /* 18: Character */
         objectOperationHandlerObjectDouble,    /* 19: Double */
@@ -558,7 +692,7 @@ public class NdbOpenJPADomainFieldHandle
         objectOperationHandlerUnsupportedType, /* 28: Calendar */
         objectOperationHandlerUnsupportedType, /* 29: OID */
         objectOperationHandlerUnsupportedType, /* 30: InputStream */
-        objectOperationHandlerUnsupportedType /* 31: InputReader */        
+        objectOperationHandlerUnsupportedType  /* 31: InputReader */        
     };
 
     public int compareTo(Object o) {
@@ -600,7 +734,10 @@ public class NdbOpenJPADomainFieldHandle
         return oidField;
     }
 
-    protected static Field getFieldForOidClass(Class<?> oidClass, String fieldName) {
+    protected static Field getFieldForOidClass(
+            NdbOpenJPADomainFieldHandlerImpl ndbOpenJPADomainFieldHandlerImpl,
+            Class<?> oidClass, String fieldName) {
+        String message = null;
         Field result = null;
         if (logger.isDetailEnabled()) logger.detail("Oid class: " + oidClass.getName());
         // the openJPAId class might be a simple type or a user-defined type
@@ -613,29 +750,38 @@ public class NdbOpenJPADomainFieldHandle
                 if (logger.isDetailEnabled()) logger.detail("OidField: " + result);
                 return result;
             } catch (NoSuchFieldException ex) {
-                logger.error("Oid class " + oidClass.getName() + " does not define a field named " + fieldName);
-                throw new ClusterJUserException(
-                        local.message("ERR_No_Field_In_Oid_Class", fieldName));
+                message = local.message("ERR_No_Field_In_Oid_Class", oidClass.getName(), fieldName);
+                logger.info(message);
+                ndbOpenJPADomainFieldHandlerImpl.setUnsupported(message);
+                return null;
             } catch (SecurityException ex) {
-                logger.error("Security exception getting Field from Oid class " + oidClass.getName());
-                throw new ClusterJUserException(
-                        local.message("ERR_Security_Violation_For_Oid_Class", oidClass.getName()));
+                message = local.message("ERR_Security_Violation_For_Oid_Class", oidClass.getName());
+                logger.info(message);
+                ndbOpenJPADomainFieldHandlerImpl.setUnsupported(message);
+                return null;
             }
         }
     }
 
     protected ObjectOperationHandler getObjectOperationHandlerRelationDelegate(int javaType) {
+        String message;
         switch (javaType) {
-            case JavaTypes.INT: return objectOperationHandlerRelationIntField;
-
-            case JavaTypes.LONG: return objectOperationHandlerRelationLongField;
+            case JavaTypes.INT:
+            case JavaTypes.INT_OBJ:
+                return objectOperationHandlerRelationIntField;
+
+            case JavaTypes.LONG:
+            case JavaTypes.LONG_OBJ:
+                return objectOperationHandlerRelationLongField;
 
-            case JavaTypes.STRING: return objectOperationHandlerRelationStringField;
+            case JavaTypes.STRING:
+                return objectOperationHandlerRelationStringField;
 
             default:
-                throw new ClusterJFatalUserException(
-                    local.message("ERR_Illegal_Primary_Key_Type",
-                    domainTypeHandler.getName(), name, javaType));
+                message = local.message("ERR_Illegal_Foreign_Key_Type",
+                        domainTypeHandler.getName(), name, columnName, javaType);
+                setUnsupported(message);
+                return null;
         }
     }
 
@@ -789,9 +935,16 @@ public class NdbOpenJPADomainFieldHandle
                 if (logger.isDetailEnabled()) logger.detail("Related object is null");
                 op.setNull(fmd.getStoreColumn());
             } else {
-                int oid = getInt(rel.getObjectId());
-                if (logger.isDetailEnabled()) logger.detail("Related object class: " + rel.getMetaData().getTypeAlias() + " key: " + oid);
-                op.setInt(fmd.getStoreColumn(), oid);
+                Object objid = rel.getObjectId();
+                if (objid == null) {
+                    // TODO: doesn't seem right
+                    op.setNull(fmd.getStoreColumn());
+                    if (logger.isDetailEnabled()) logger.detail("Related object class: " + rel.getMetaData().getTypeAlias() + " object id: " + objid);
+                } else {
+                    int oid = getInt(objid);
+                    if (logger.isDetailEnabled()) logger.detail("Related object class: " + rel.getMetaData().getTypeAlias() + " key: " + oid);
+                    op.setInt(fmd.getStoreColumn(), oid);
+                }
             }
         }
 
@@ -1025,7 +1178,7 @@ public class NdbOpenJPADomainFieldHandle
          * 
          * @param fmd the domain field handler
          * @param oid the value to set
-         * @param type the bound type (i.e. EQ, NE, LE, LT, GE, GT)
+         * @param type the bound type (i.e. EQ, LE, LT, GE, GT)
          * @param op the index operation
          */
         public void operationSetBounds(AbstractDomainFieldHandlerImpl fmd, Object oid, BoundType type, IndexScanOperation op) {
@@ -1042,4 +1195,17 @@ public class NdbOpenJPADomainFieldHandle
         return storeColumns;
     }
 
+    public boolean isSupported() {
+        return supported;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    private void setUnsupported(String reason) {
+        this.supported = false;
+        this.reason = reason;
+    }
+
 }

=== modified file 'storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainTypeHandlerImpl.java'
--- a/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainTypeHandlerImpl.java	2010-01-22 16:07:59 +0000
+++ b/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPADomainTypeHandlerImpl.java	2010-03-12 09:31:36 +0000
@@ -18,8 +18,10 @@
 
 package com.mysql.clusterj.openjpa;
 
+import java.lang.reflect.Modifier;
 import java.sql.SQLException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.BitSet;
 import java.util.HashSet;
 import java.util.List;
@@ -33,14 +35,12 @@ import org.apache.openjpa.kernel.PCState
 
 import com.mysql.clusterj.ClusterJFatalInternalException;
 import com.mysql.clusterj.core.CacheManager;
-import com.mysql.clusterj.core.metadata.DomainFieldHandlerImpl;
 import com.mysql.clusterj.core.metadata.IndexHandlerImpl;
 import com.mysql.clusterj.core.metadata.KeyValueHandlerImpl;
 import com.mysql.clusterj.core.query.CandidateIndexImpl;
 import com.mysql.clusterj.core.spi.DomainFieldHandler;
 import com.mysql.clusterj.core.spi.DomainTypeHandler;
 import com.mysql.clusterj.core.spi.ValueHandler;
-import com.mysql.clusterj.core.store.ClusterTransaction;
 import com.mysql.clusterj.core.store.Dictionary;
 import com.mysql.clusterj.core.store.Operation;
 import com.mysql.clusterj.core.store.PartitionKey;
@@ -73,8 +73,6 @@ public class NdbOpenJPADomainTypeHandler
             new ArrayList<NdbOpenJPADomainFieldHandlerImpl>();
     private ClassMapping classMapping;
 
-    /** Reason for this class to be unsupported. */
-    private Object unsupportedReason = null;
     /** The field handlers for this persistent type*/
     private NdbOpenJPADomainFieldHandlerImpl[] fieldHandlers;
 
@@ -91,19 +89,51 @@ public class NdbOpenJPADomainTypeHandler
 
     private NdbOpenJPADomainFieldHandlerImpl[] partitionKeyFieldHandlers;
 
+    private NdbOpenJPAConfigurationImpl domainTypeHandlerFactory;
+
+    private Dictionary dictionary;
+
+    private Set<NdbOpenJPADomainTypeHandlerImpl<?>> dependencies =
+        new HashSet<NdbOpenJPADomainTypeHandlerImpl<?>>();
+
+    private Status status = Status.IN_PROCESS;
+
+    /** Reasons why this class is not supported by clusterjpa */
+    private List<String> reasons = new ArrayList<String>();
+
     @SuppressWarnings("unchecked")
     NdbOpenJPADomainTypeHandlerImpl(
             Dictionary dictionary, ClassMapping classMapping, 
             NdbOpenJPAConfigurationImpl domainTypeHandlerFactory) {
+        String message = null;
+        this.dictionary = dictionary;
+        this.domainTypeHandlerFactory = domainTypeHandlerFactory;
         this.classMapping = classMapping;
         classMapping.resolve(0xffffffff);
         oidClass = classMapping.getObjectIdType();
         this.describedType = classMapping.getDescribedType();
+        if (classMapping.getPCSuperclass() != null) {
+            // persistent subclasses are not supported
+            message = local.message("ERR_Subclass", this.describedType);
+            setUnsupported(message);
+        }
+        if (classMapping.getPCSubclasses() != null && classMapping.getPCSubclasses().length > 0) {
+            // persistent superclasses are not supported
+            message = local.message("ERR_Superclass", this.describedType);
+            setUnsupported(message);
+        }
+        int modifiers = describedType.getClass().getModifiers();
+        if (Modifier.isAbstract(modifiers)) {
+            // abstract classes are not supported
+            message = local.message("ERR_Abstract_Class", describedType.getClass().getName());
+            setUnsupported(message);
+        }
         this.typeName = describedType.getName();
         this.tableName = classMapping.getTable().getFullName();
         this.storeTable = dictionary.getTable(tableName);
         if (logger.isTraceEnabled()) {
-            logger.trace("initialize for class: " + typeName + " mapped to table: " + storeTable.getName());
+            logger.trace("initialize for class: " + typeName
+                    + " mapped to table: " + storeTable.getName());
         }
         
         // set up the partition keys
@@ -111,17 +141,26 @@ public class NdbOpenJPADomainTypeHandler
         partitionKeyColumnNames = storeTable.getPartitionKeyColumnNames();
         numberOfPartitionKeyColumns = partitionKeyColumnNames.length;
         partitionKeyFieldHandlers = new NdbOpenJPADomainFieldHandlerImpl[numberOfPartitionKeyColumns];
-
+        if (logger.isDetailEnabled()) {
+            logger.detail("partition key columns for class: "+ typeName
+                    + " partition key columns: " + numberOfPartitionKeyColumns
+                    + " names: " + Arrays.toString(partitionKeyColumnNames));
+        }
+        // set up the fields
         for (FieldMapping fm: classMapping.getDefinedFieldMappings()) {
             NdbOpenJPADomainFieldHandlerImpl fmd = new NdbOpenJPADomainFieldHandlerImpl(
                     dictionary, this, domainTypeHandlerFactory, fm);
             fields.add(fmd);
-            // add column names to allColumnNames
-            for (com.mysql.clusterj.core.store.Column column: fmd.getStoreColumns()) {
-                allStoreColumns.add(column);
-            }
-            if (fmd.isPrimaryKey()) {
-                primaryKeyFields.add(fmd);
+            if (!fmd.isSupported()) {
+                setUnsupported(fmd.getReason());
+            } else {
+                // add column names to allColumnNames
+                for (com.mysql.clusterj.core.store.Column column: fmd.getStoreColumns()) {
+                    allStoreColumns.add(column);
+                }
+                if (fmd.isPrimaryKey()) {
+                    primaryKeyFields.add(fmd);
+                }
             }
         }
         primaryKeyFieldNumbers = new int[primaryKeyFields.size()];
@@ -130,6 +169,13 @@ public class NdbOpenJPADomainTypeHandler
             primaryKeyFieldNumbers[i++] = fmd.getFieldNumber();
         }
         fieldHandlers = fields.toArray(new NdbOpenJPADomainFieldHandlerImpl[fields.size()]);
+        // check to make sure all partition keys have registered
+        for (int j = 0; j < numberOfPartitionKeyColumns; ++j) {
+            if (partitionKeyFieldHandlers[j] == null) {
+                setUnsupported();
+                reasons.add("Unmapped partition key " + partitionKeyColumnNames[j]);
+            }
+        }
     }
 
     /** Register a primary key column field. This is used to associate
@@ -146,6 +192,11 @@ public class NdbOpenJPADomainTypeHandler
         for (int j = 0; j < partitionKeyColumnNames.length; ++j) {
             if (partitionKeyColumnNames[j].equals(columnName)) {
                 partitionKeyFieldHandlers[j] = fmd;
+            } else {
+                if (logger.isDetailEnabled()) logger.detail(
+                        "NdbOpenJPADomainTypeHandlerImpl.registerPrimaryKeyColumn "
+                        + "mismatch between partition key column name: " + partitionKeyColumnNames[j]
+                        + " and primary key column name: " + columnName);
             }
         }
         return;
@@ -232,7 +283,8 @@ public class NdbOpenJPADomainTypeHandler
     public void operationSetKeys(ValueHandler handler, Operation op) {
         for (NdbOpenJPADomainFieldHandlerImpl fmd: primaryKeyFields) {
             if (logger.isDetailEnabled()) {
-                logger.detail("Class: " + typeName + " Primary Key Field: " + fmd.getName() + handler.pkToString(this));
+                logger.detail("Class: " + typeName
+                        + " Primary Key Field: " + fmd.getName() + handler.pkToString(this));
             }
             fmd.operationSetValue(handler, op);
         }
@@ -253,7 +305,7 @@ public class NdbOpenJPADomainTypeHandler
             }
         } catch (Exception exception) {
             exception.printStackTrace();
-            throw new RuntimeException("NdbOpenJPADomainTypeHandlerImpl.operationSetValuesExcept caught " + exception);
+            throw new RuntimeException("NdbOpenJPADomainTypeHandlerImpl.operationSetValuesExcept caught exception", exception);
         }
     }
 
@@ -313,10 +365,6 @@ public class NdbOpenJPADomainTypeHandler
         return new NdbOpenJPAValueHandler(sm, store);
     }
 
-    public boolean isSupportedType() {
-        return unsupportedReason == null;
-    }
-
     public int[] getKeyFieldNumbers() {
         return primaryKeyFieldNumbers;
     }
@@ -356,7 +404,9 @@ public class NdbOpenJPADomainTypeHandler
                 // this field is not loaded
                 NdbOpenJPADomainFieldHandlerImpl fieldHandler = fieldHandlers[i];
                 loadedAny = true;
-                if (logger.isDebugEnabled()) logger.debug("loading field " + fieldHandler.getName() + " for column " + fieldHandler.getColumnName());
+                if (logger.isDebugEnabled()) logger.debug(
+                        "loading field " + fieldHandler.getName()
+                        + " for column " + fieldHandler.getColumnName());
                 fieldHandler.load(sm, store, fetch);
             }
         }
@@ -372,7 +422,8 @@ public class NdbOpenJPADomainTypeHandler
     public void load(OpenJPAStateManager sm, NdbOpenJPAStoreManager store, 
             JDBCFetchConfiguration fetch, NdbOpenJPAResult result) throws SQLException {
         for (NdbOpenJPADomainFieldHandlerImpl fieldHandler: fieldHandlers) {
-            if (logger.isDebugEnabled()) logger.debug("loading field " + fieldHandler.getName() + " for column " + fieldHandler.getColumnName() + " from result data.");
+            if (logger.isDebugEnabled()) logger.debug("loading field " + fieldHandler.getName()
+                    + " for column " + fieldHandler.getColumnName() + " from result data.");
             fieldHandler.load(sm, store, fetch, result);
         }
     }
@@ -461,4 +512,124 @@ public class NdbOpenJPADomainTypeHandler
         return result;
     }
 
+    /** Register a dependency on another class. If the class is not already known,
+     * add it to the list of dependencies.
+     */
+    public NdbOpenJPADomainTypeHandlerImpl<?> registerDependency(ClassMapping mapping) {
+        NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler = 
+            domainTypeHandlerFactory.getDomainTypeHandler(mapping, dictionary);
+        dependencies.add(domainTypeHandler);
+        return domainTypeHandler;
+    }
+
+    /** Status of this class with regard to usability with clusterjpa.
+     * 
+     */
+    private enum Status {
+        IN_PROCESS,
+        GOOD,
+        BAD;
+    }
+
+    private Status supportStatus() {
+        return status;
+    }
+
+    public void initializeRelations() {
+        for (NdbOpenJPADomainFieldHandlerImpl fieldHandler: fieldHandlers) {
+            fieldHandler.initializeRelations();
+        }
+
+        // iterate the dependencies and see if any are not supported
+        boolean supported = status != Status.BAD;
+        boolean workToDo = !supported;
+        for (NdbOpenJPADomainTypeHandlerImpl<?> dependent: dependencies) {
+            // top level class will have recursive list of dependencies including itself
+            this.dependencies.addAll(dependent.getDependencies());
+            switch (dependent.supportStatus()) {
+                case IN_PROCESS:
+                    workToDo = true;
+                    break;
+                case GOOD:
+                    break;
+                case BAD:
+                    setUnsupported();
+                    supported = false;
+                    workToDo = true;
+                    String message = local.message("ERR_Bad_Dependency", dependent.typeName);
+                    reasons.add(message);
+                    if (logger.isDebugEnabled()) logger.debug(message);
+            }
+            String message = "Processing class " + typeName + " found dependency " + dependent.typeName
+            + " support status is: " + dependent.supportStatus();
+            if (logger.isDetailEnabled()) logger.detail(message);
+        }
+        if (workToDo) {
+            if (!supported) {
+                // found an unsupported class in the dependency list
+                for (NdbOpenJPADomainTypeHandlerImpl<?> dependent: dependencies) {
+                    dependent.setUnsupported();
+                }
+            } else {
+                for (NdbOpenJPADomainTypeHandlerImpl<?> dependent: dependencies) {
+                    dependent.setSupported();
+                }
+            }
+        } else {
+            this.setSupported();
+        }
+        if (logger.isDetailEnabled()) logger.detail("Processing class " + typeName + " has dependencies " + dependencies);
+        if (logger.isDetailEnabled()) logger.detail("Processing class " + typeName + " has dependencies " + dependencies);
+    }
+
+    private Set<NdbOpenJPADomainTypeHandlerImpl<?>> getDependencies() {
+        return dependencies;
+    }
+
+    private void setUnsupported() {
+        if (status != Status.BAD) {
+            if (logger.isDetailEnabled()) logger.detail("Class " + typeName + " marked as BAD.");
+            status = Status.BAD;
+        }
+    }
+
+    private void setUnsupported(String reason) {
+        if (status != Status.BAD) {
+            if (logger.isDetailEnabled()) logger.detail("Class " + typeName + " marked as BAD.");
+            status = Status.BAD;
+        }
+        reasons.add(reason);
+    }
+
+    private void setSupported() {
+        if (status != Status.GOOD) {
+            if (logger.isDetailEnabled()) logger.detail("Class " + typeName + " marked as GOOD.");
+            status = Status.GOOD;
+        }
+    }
+
+    public boolean isSupportedType() {
+        return Status.GOOD == status;
+    }
+
+    public String getReasons() {
+        if (reasons.size() == 0) {
+            return null;
+        }
+        StringBuilder result = new StringBuilder(
+                local.message("MSG_Unsupported_Class", getName()));
+        for (String reason:reasons) {
+            result.append('\n');
+            result.append(reason);
+            result.append(';');
+        }
+        result.append('\n');
+        return result.toString();
+    }
+
+    @Override
+    public String toString() {
+        return "NdbOpenJPADomainTypeHandlerImpl:" + typeName;
+    }
+
 }

=== modified file 'storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAResult.java'
--- a/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAResult.java	2010-03-01 06:59:49 +0000
+++ b/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAResult.java	2010-03-12 09:31:36 +0000
@@ -157,6 +157,10 @@ public class NdbOpenJPAResult extends Ab
             case JavaSQLTypes.BYTES:
                 result = resultData.getBytes(columnName);
                 break;
+            case JavaTypes.BOOLEAN:
+            case JavaTypes.BOOLEAN_OBJ:
+                result = resultData.getObjectBoolean(columnName);
+                break;
             default:
                 if (logger.isDetailEnabled()) {
                     logger.detail("Unsupported Meta Type: " + metaType);

=== modified file 'storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAStoreManager.java'
--- a/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAStoreManager.java	2010-01-22 16:07:59 +0000
+++ b/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAStoreManager.java	2010-03-12 09:31:36 +0000
@@ -43,6 +43,8 @@ import org.apache.openjpa.util.OpenJPAId
 
 import com.mysql.clusterj.ClusterJDatastoreException;
 import com.mysql.clusterj.ClusterJException;
+import com.mysql.clusterj.ClusterJFatalInternalException;
+import com.mysql.clusterj.ClusterJFatalUserException;
 import com.mysql.clusterj.ClusterJUserException;
 import com.mysql.clusterj.SessionFactory;
 import com.mysql.clusterj.Transaction;
@@ -92,6 +94,7 @@ public class NdbOpenJPAStoreManager exte
         storeContext = ctx;
         ndbConfiguration = conf;
         sessionFactory = conf.getSessionFactory();
+        getSession();
     }
 
     protected NdbOpenJPADomainTypeHandlerImpl<?> getDomainTypeHandler(OpenJPAStateManager sm) {
@@ -111,7 +114,7 @@ public class NdbOpenJPAStoreManager exte
         return session.deletePersistentAll(base);
     }
 
-    private SessionSPI getSession() {
+    protected SessionSPI getSession() {
         if (session == null) {
             session = (SessionSPI) sessionFactory.getSession();
             dictionary = session.getDictionary();
@@ -125,7 +128,8 @@ public class NdbOpenJPAStoreManager exte
     public Object find(Object oid, ValueMapping vm,
         JDBCFetchConfiguration fetch) {
         if (logger.isDebugEnabled()) {
-            logger.debug("NdbStoreManager.find(Object oid, ValueMapping vm, JDBCFetchConfiguration fetch) delegated to super.");
+            logger.debug("NdbStoreManager.find(Object oid, ValueMapping vm, "
+                    + "JDBCFetchConfiguration fetch) delegated to super.");
         }
         return super.find(oid, vm, fetch);
     }
@@ -144,7 +148,8 @@ public class NdbOpenJPAStoreManager exte
     public boolean load(OpenJPAStateManager sm, BitSet fields,
             FetchConfiguration fetch, int lockLevel, Object context) {
         if (logger.isDebugEnabled()) {
-            logger.debug("NdbStoreManager.load(OpenJPAStateManager sm, BitSet fields, FetchConfiguration fetch, int lockLevel, Object context)...");
+            logger.debug("NdbStoreManager.load(OpenJPAStateManager sm, BitSet fields, "
+                    + "FetchConfiguration fetch, int lockLevel, Object context)...");
             logger.debug("Id: " + sm.getId() + " requested fields: " + printBitSet(sm, fields));
         }
         NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler = getDomainTypeHandler(sm);
@@ -162,7 +167,9 @@ public class NdbOpenJPAStoreManager exte
     public Object load(ClassMapping mapping, JDBCFetchConfiguration fetch,
         BitSet exclude, Result result) throws SQLException {
         if (logger.isDebugEnabled()) {
-            logger.debug("NdbStoreManager.load(ClassMapping mapping, JDBCFetchConfiguration fetch, BitSet exclude, Result result) for " +  mapping.getDescribedType().getName() + " delegated to super.");
+            logger.debug("NdbStoreManager.load(ClassMapping mapping, JDBCFetchConfiguration fetch, "
+                    + "BitSet exclude, Result result) for " +  mapping.getDescribedType().getName()
+                    + " delegated to super.");
         }
         return super.load(mapping, fetch, exclude, result);
     }
@@ -172,7 +179,8 @@ public class NdbOpenJPAStoreManager exte
     public Collection loadAll(Collection sms, PCState state, int load,
         FetchConfiguration fetch, Object context) {
         if (logger.isDebugEnabled()) {
-            logger.debug("NdbStoreManager.loadAll(Collection sms, PCState state, int load, FetchConfiguration fetch, Object context) delegated to super.");
+            logger.debug("NdbStoreManager.loadAll(Collection sms, PCState state, int load, "
+                    + "FetchConfiguration fetch, Object context) delegated to super.");
         }
         return super.loadAll(sms, state, load, fetch, context);
     }
@@ -181,20 +189,37 @@ public class NdbOpenJPAStoreManager exte
     public boolean initialize(OpenJPAStateManager sm, PCState state,
         FetchConfiguration fetch, Object context) {
         if (logger.isDebugEnabled()) {
-            logger.debug("NdbStoreManager.initialize(OpenJPAStateManager sm, PCState state, FetchConfiguration fetch, Object context)");
+            logger.debug("NdbStoreManager.initialize(OpenJPAStateManager sm, PCState state, "
+                    + "FetchConfiguration fetch, Object context)");
         }
         // TODO: support user-defined oid types
         OpenJPAId id = (OpenJPAId)sm.getId();
         if (logger.isTraceEnabled()) {
             logger.trace("Id: " + id.getClass() + " " + id);
         }
+        // get domain type handler for StateManager
+        NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler = getDomainTypeHandler(sm);
 
+        if (!domainTypeHandler.isSupportedType()) {
+            if (logger.isDebugEnabled()) logger.debug(
+                    "NdbOpenJPAStoreManager.initialize found unsupported class " + domainTypeHandler.getName());
+            if (ndbConfiguration.getFailOnJDBCPath()) {
+                throw new ClusterJFatalUserException(
+                        local.message("ERR_JDBC_Path", domainTypeHandler.getName()));
+            }
+            // if not supported, go the jdbc route
+            boolean result = super.initialize(sm, state, fetch, context);
+            if (logger.isDebugEnabled()) logger.debug(
+                    "NdbOpenJPAStoreManager.initialize delegated to super: returned " + result);
+            return result;
+        }
         try {
             // get session from session factory
             getSession();
+            session.startAutoTransaction();
             // get domain type handler for StateManager
-            NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler =
-                    getDomainTypeHandler(sm);
+//            NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler =
+//                    getDomainTypeHandler(sm);
 //                Object instance = session.initializeFromDatabase(
 //                    domainTypeHandler, null,
 //                    domainTypeHandler.getValueHandler(sm),
@@ -229,12 +254,18 @@ public class NdbOpenJPAStoreManager exte
                         sm.getPCState().getClass().getSimpleName() + " " +
                         printLoaded(sm));
             }
+            session.endAutoTransaction();
             return true;
 
+        } catch (ClusterJException e) {
+            session.failAutoTransaction();
+            throw e;
         } catch (Exception e) {
+            session.failAutoTransaction();
             e.printStackTrace();
+            throw new ClusterJFatalInternalException("Unexpected exception.", e);
             // if any problem, fall back
-            return super.initialize(sm, state, fetch, context);
+            // return super.initialize(sm, state, fetch, context);
         }
     }
 
@@ -280,6 +311,12 @@ public class NdbOpenJPAStoreManager exte
         for (OpenJPAStateManager sm: stateManagers) {
             DomainTypeHandler<?> domainTypeHandler = getDomainTypeHandler(sm);
             if (!domainTypeHandler.isSupportedType()) {
+                if (logger.isDetailEnabled()) logger.detail("Found unsupported class "
+                        + domainTypeHandler.getName());
+                if (ndbConfiguration.getFailOnJDBCPath()) {
+                    throw new ClusterJFatalUserException(
+                            local.message("ERR_JDBC_Path", domainTypeHandler.getName()));
+                }
                 allSupportedTypes = false;
             }
             if (logger.isTraceEnabled()) {
@@ -290,7 +327,11 @@ public class NdbOpenJPAStoreManager exte
                 logger.trace(buffer.toString());
         }
         if (!allSupportedTypes) {
-            return super.flush(sms);
+            // not all instances are of supported types; delegate to super
+            Collection<Exception> exceptions = super.flush(sms);
+            if (logger.isDetailEnabled()) logger.detail("Found unsupported class(es); "
+                    + "super resulted in exceptions: " + exceptions);
+            return exceptions;
         }
         // now flush changes to the cluster back end
         getSession();
@@ -312,6 +353,11 @@ public class NdbOpenJPAStoreManager exte
                 } else if (pcState == PCState.PDIRTY) {
                     // flush dirty instance
                     session.update(domainTypeHandler, valueHandler);
+                } else if (pcState == PCState.PNEWFLUSHEDDELETED) {
+                    // flush new flushed deleted instance
+                    session.delete(domainTypeHandler, valueHandler);
+                } else if (pcState == PCState.PNEWFLUSHEDDELETEDFLUSHED) {
+                    // nothing to do
                 } else {
                     throw new ClusterJUserException(
                             local.message("ERR_Unsupported_Flush_Operation",
@@ -352,7 +398,7 @@ public class NdbOpenJPAStoreManager exte
         if (logger.isTraceEnabled()) {
             logger.trace(" Transaction " + hashCode() + printIsActive(tx));
         }
-//        super.beginOptimistic();
+        super.beginOptimistic();
         try {
             getSession();
             tx = session.currentTransaction();
@@ -384,7 +430,7 @@ public class NdbOpenJPAStoreManager exte
                     e.getMessage());
         }
         // TODO: handle JDBC connection for queries
-//        super.begin();
+        super.begin();
     }
 
     @Override
@@ -398,7 +444,7 @@ public class NdbOpenJPAStoreManager exte
                     local.message("ERR_Commit_Failed", ex.toString()));
         }
         // TODO: handle JDBC connection for queries
-//        super.commit();
+        super.commit();
     }
 
     @Override
@@ -406,7 +452,7 @@ public class NdbOpenJPAStoreManager exte
         if (logger.isTraceEnabled()) {logger.trace(" Transaction " + hashCode() + printIsActive(tx));}
         session.rollback();
         // TODO: handle JDBC connection for queries
-//        super.rollback();
+        super.rollback();
     }
 
     @Override
@@ -484,7 +530,7 @@ public class NdbOpenJPAStoreManager exte
      * @return the query domain type
      */
     public <T> QueryDomainType<T> createQueryDomainType(Class<T> type) {
-	return session.getQueryBuilder().createQueryDefinition(type);
+        return session.getQueryBuilder().createQueryDefinition(type);
     }
 
     /** Execute the query and return the result list. 

=== modified file 'storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAStoreQuery.java'
--- a/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAStoreQuery.java	2010-01-22 16:07:59 +0000
+++ b/storage/ndb/clusterj/clusterj-openjpa/src/main/java/com/mysql/clusterj/openjpa/NdbOpenJPAStoreQuery.java	2010-03-12 09:31:36 +0000
@@ -50,23 +50,26 @@ public class NdbOpenJPAStoreQuery extend
         ClassMetaData[] metas, boolean subclasses, ExpressionFactory[] facts,
         QueryExpressions[] exps, Object[] params) {
         if (logger.isDebugEnabled()) {
-            logger.debug("NdbStoreManager.executeDelete(Executor ex, ClassMetaData base, " +
+            logger.debug("NdbOpenJPAStoreQuery.executeDelete(Executor ex, ClassMetaData base, " +
                     "ClassMetaData[] metas, boolean subclasses, ExpressionFactory[] facts, " +
-                    "QueryExpressions[] exps, Object[] params) maybe delegated to super.\n" +
+                    "QueryExpressions[] exps, Object[] params).\n" +
                     "Class: " + base.getTypeAlias() + 
                     " query expressions: " + exps + "[" + exps.length + "]" +
                     " exps[0].filter: " + exps[0].filter);
         }
-        if (exps.length == 1 && exps[0].filter.getClass().getName().contains("EmptyExpression")) {
+        NdbOpenJPAStoreManager store = (NdbOpenJPAStoreManager)getStore();
+        NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler = store.getDomainTypeHandler((ClassMapping)base);
+        if (domainTypeHandler.isSupportedType() 
+                && exps.length == 1 
+                && exps[0].filter.getClass().getName().contains("EmptyExpression")) {
             // filter is empty so delete the entire extent
             if (logger.isDebugEnabled()) {
                 logger.debug("Empty Expression for delete will delete the entire extent.");
             }
-            NdbOpenJPAStoreManager store = (NdbOpenJPAStoreManager)getStore();
-            NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler = store.getDomainTypeHandler((ClassMapping)base);
             int count = store.deleteAll(domainTypeHandler);
             return count;
         } else {
+            if (logger.isDebugEnabled()) logger.debug("NdbOpenJPAStoreQuery.executeDelete delegated to super.");
             return super.executeDelete(ex, base, metas, subclasses, facts, exps, params);
         }
     }

=== modified file 'storage/ndb/clusterj/clusterj-openjpa/src/main/resources/com/mysql/clusterj/openjpa/Bundle.properties'
--- a/storage/ndb/clusterj/clusterj-openjpa/src/main/resources/com/mysql/clusterj/openjpa/Bundle.properties	2010-01-22 16:07:59 +0000
+++ b/storage/ndb/clusterj/clusterj-openjpa/src/main/resources/com/mysql/clusterj/openjpa/Bundle.properties	2010-03-12 09:31:36 +0000
@@ -1,9 +1,9 @@
 ERR_More_Than_One_Column_Mapped_To_A_Field:Cannot map more than one column \
 to a field. class: {0}, field: {1} columns: {2}.
-ERR_Illegal_Primary_Key_Type:Illegal Primary Key type for \
-class: {0} field: {1} Java type: {2}.
-ERR_Illegal_Foreign_Key_Type:Illegal Foreign Key type for \
-class: {0} field: {1} Java type: {2}.
+ERR_Illegal_Primary_Key_Type:Unsupported Primary Key type for \
+class: {0} field: {1} column: {2} Java type: {3}.
+ERR_Illegal_Foreign_Key_Type:Unsupported Foreign Key type for \
+class: {0} field: {1} column: {2} Java type: {3}.
 ERR_Unsupported_Flush_Operation:Unsupported PCType for flush operation: {0}.
 ERR_Commit_Failed:Commit failed: {0}
 ERR_No_Column_Mapped_To_A_Field:Must map a column to a field: \
@@ -12,8 +12,8 @@ ERR_Unsupported_Meta_Type:MetaType {0} n
 ERR_Datastore_Exception:Exception caught.
 ERR_Unsupported_Object_Type_For_Resolve:Unsupported object type {0} for resolve.
 ERR_Implementation_Should_Not_Occur:Implementation error; should not occur.
-ERR_No_Oid_Field:There is no field defined for column {0}.
-ERR_No_Field_In_Oid_Class:Oid class does not have a field named {0}.
+ERR_No_Oid_Field:There is no oid field defined for column {0}.
+ERR_No_Field_In_Oid_Class:Oid class {0} does not have a field named {1}.
 ERR_Security_Violation_For_Oid_Class:Security violation getting field for oid class {0}.
 ERR_Illegal_Filter_Condition:Illegal filter condition for composite key {0}.
 ERR_Create_Domain_Type_Handler_First:The DomainTypeHandler for {0} must be created \
@@ -27,3 +27,10 @@ ERR_No_Columns_And_Not_Mapped_By:For typ
 must be mapped by a related field.
 ERR_Embedded_Fields_Not_Supported:For type {0} field {1}, embedded fields are not supported.
 ERR_Partition_Key_Null:Partition key must not be null.
+ERR_Bad_Dependency:This class has a dependency on class {0} which is not supported.
+ERR_JDBC_Path:Force failure on access of unsupported class {0}.
+MSG_Unsupported_Class:Class {0} is not supported.
+ERR_No_Column:For field {0}, table {1} does not define column {2}.
+ERR_Abstract_Class:Class {0} is abstract and is not supported.
+ERR_Subclass:Class {0} is a persistent subclass and is not supported.
+ERR_Superclass:Class {0} is a persistent superclass and is not supported.

=== modified file 'storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryInTest.java'
--- a/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryInTest.java	2010-01-26 10:46:42 +0000
+++ b/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryInTest.java	2010-03-12 09:31:36 +0000
@@ -18,6 +18,9 @@ Foundation, Inc., 51 Franklin St, Fifth 
 
 package testsuite.clusterj;
 
+import java.util.Arrays;
+import java.util.HashSet;
+
 import com.mysql.clusterj.ClusterJUserException;
 
 import testsuite.clusterj.model.AllPrimitives;
@@ -86,6 +89,11 @@ public class QueryInTest extends Abstrac
         equalOrInQuery("int_not_null_btree", 4, "int_null_none", new Object[] {6, 9}, "none", 4, 6, 9);
         equalOrInQuery("int_null_btree", 4, "int_null_none", new Object[] {4, 6, 9}, "none", 4, 6, 9);
         equalOrInQuery("int_null_btree", 4, "int_null_none", new Object[] {6, 6, 6, 9}, "none", 4, 6, 9);
+
+        equalOrInQuery("int_not_null_btree", 4, "int_null_none", Arrays.asList(new Object[] {}), "none", 4);
+        equalOrInQuery("int_not_null_btree", 4, "int_null_none", Arrays.asList(new Integer[] {6, 9}), "none", 4, 6, 9);
+        equalOrInQuery("int_null_btree", 4, "int_null_none", new HashSet<Integer>(Arrays.asList(new Integer[] {4, 6, 9})), "none", 4, 6, 9);
+        equalOrInQuery("int_null_btree", 4, "int_null_none", new HashSet<Integer>(Arrays.asList(new Integer[] {6, 6, 6, 9})), "none", 4, 6, 9);
         failOnError();        
     }
 

=== modified file 'storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/TimestampAsUtilDateTypesTest.java'
--- a/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/TimestampAsUtilDateTypesTest.java	2010-01-22 16:07:59 +0000
+++ b/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/TimestampAsUtilDateTypesTest.java	2010-03-12 09:31:36 +0000
@@ -24,6 +24,8 @@ import java.sql.SQLException;
 import java.sql.Timestamp;
 import java.util.Date;
 
+import org.junit.Ignore;
+
 import testsuite.clusterj.model.IdBase;
 import testsuite.clusterj.model.TimestampAsUtilDateTypes;
 
@@ -48,6 +50,7 @@ create index idx_timestamp_not_null_btre
 create unique index idx_timestamp_not_null_both on timestamptypes(timestamp_not_null_both);
 
  */
+@Ignore
 public class TimestampAsUtilDateTypesTest extends AbstractClusterJModelTest {
 
     @Override

=== modified file 'storage/ndb/clusterj/clusterj-tie/pom.xml'
--- a/storage/ndb/clusterj/clusterj-tie/pom.xml	2010-03-08 11:13:02 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/pom.xml	2010-03-12 09:31:36 +0000
@@ -108,7 +108,7 @@
         <configuration>
           <instructions>
             <Export-Package>com.mysql.clusterj.tie.*</Export-Package>
-            <Import-Package>com.mysql.clusterj,com.mysql.clusterj.core.store,com.mysql.clusterj.core.util,com.mysql.ndbjtie.mysql,com.mysql.ndbjtie.ndbapi</Import-Package>
+            <Import-Package>com.mysql.clusterj,com.mysql.clusterj.core.store,com.mysql.clusterj.core.query,com.mysql.clusterj.core.util,com.mysql.ndbjtie.mysql,com.mysql.ndbjtie.ndbapi</Import-Package>
           </instructions>
         </configuration>
       </plugin>

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DictionaryImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DictionaryImpl.java	2010-01-22 16:07:59 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DictionaryImpl.java	2010-03-12 09:31:36 +0000
@@ -51,7 +51,7 @@ class DictionaryImpl implements com.mysq
     public Table getTable(String tableName) {
         TableConst ndbTable = ndbDictionary.getTable(tableName);
         if (ndbTable == null) {
-            // try the lower case name in case it's a simple user misunderstanding
+            // try the lower case table name
             ndbTable = ndbDictionary.getTable(tableName.toLowerCase());
         }
         handleError(ndbTable, ndbDictionary, tableName);
@@ -62,6 +62,10 @@ class DictionaryImpl implements com.mysq
 
     public Index getIndex(String indexName, String tableName, String indexAlias) {
         IndexConst ndbIndex = ndbDictionary.getIndex(indexName, tableName);
+        if (ndbIndex == null) {
+            // try the lower case table name
+            ndbIndex = ndbDictionary.getIndex(indexName, tableName.toLowerCase());
+        }
         handleError(ndbIndex, ndbDictionary, indexAlias);
         return new IndexImpl(ndbIndex, indexAlias);
     }

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanFilterImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanFilterImpl.java	2010-01-26 10:46:42 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanFilterImpl.java	2010-03-12 09:31:36 +0000
@@ -202,4 +202,8 @@ class ScanFilterImpl implements ScanFilt
         }
     }
 
+    public void delete() {
+        NdbScanFilter.delete(ndbScanFilter);
+    }
+
 }

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java	2010-01-22 16:07:59 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanOperationImpl.java	2010-03-12 09:31:36 +0000
@@ -23,6 +23,7 @@ import com.mysql.ndbjtie.ndbapi.NdbOpera
 import com.mysql.ndbjtie.ndbapi.NdbScanFilter;
 import com.mysql.ndbjtie.ndbapi.NdbScanOperation;
 
+import com.mysql.clusterj.core.query.QueryExecutionContextImpl;
 import com.mysql.clusterj.core.store.ResultData;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
@@ -48,10 +49,12 @@ class ScanOperationImpl extends Operatio
         handleError(returnCode, ndbScanOperation);
     }
 
-    public ScanFilter getScanFilter() {
+    public ScanFilter getScanFilter(QueryExecutionContextImpl context) {
         NdbScanFilter ndbScanFilter = NdbScanFilter.create(ndbScanOperation);
         handleError(ndbScanFilter, ndbScanOperation);
-        return new ScanFilterImpl(ndbScanFilter);
+        ScanFilter scanFilter = new ScanFilterImpl(ndbScanFilter);
+        context.addFilter(scanFilter);
+        return scanFilter;
     }
 
     public int nextResult(boolean fetch) {

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/TableImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/TableImpl.java	2010-01-22 16:07:59 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/TableImpl.java	2010-03-12 09:31:36 +0000
@@ -80,8 +80,7 @@ class TableImpl implements Table {
     public ColumnImpl getColumn(String columnName) {
         ColumnConst ndbColumn = ndbTable.getColumn(columnName);
         if (ndbColumn == null) {
-            throw new ClusterJUserException(
-                    local.message("ERR_No_Column", ndbTable.getName(), columnName));
+            return null;
         }
         return new ColumnImpl(ndbTable, ndbColumn);
     }

=== modified file 'storage/ndb/src/ndbjtie/jtie/test/myapi/Makefile.am'
--- a/storage/ndb/src/ndbjtie/jtie/test/myapi/Makefile.am	2010-02-13 08:01:08 +0000
+++ b/storage/ndb/src/ndbjtie/jtie/test/myapi/Makefile.am	2010-03-12 09:30:44 +0000
@@ -19,7 +19,7 @@ include $(top_srcdir)/storage/ndb/config
 ## ----------------------------------------------------------------------
 
 ## automake flags (overridden by per-target flags, added before user flags)
-AM_CPPFLAGS = -I../../../utils
+AM_CPPFLAGS = -I../../../utils -I$(top_srcdir)/storage/ndb/include
 
 ## ----------------------------------------------------------------------
 

=== modified file 'storage/ndb/src/ndbjtie/jtie/test/myjapi/Makefile.am'
--- a/storage/ndb/src/ndbjtie/jtie/test/myjapi/Makefile.am	2010-03-01 19:24:42 +0000
+++ b/storage/ndb/src/ndbjtie/jtie/test/myjapi/Makefile.am	2010-03-12 09:30:44 +0000
@@ -95,6 +95,7 @@ javah: $(MYJAPI_CLASSES)
 
 ## automake flags (overridden by per-target flags, added before user flags)
 AM_CPPFLAGS = \
+	-I$(top_srcdir)/storage/ndb/include \
 	-I../../../utils \
 	-I../.. \
 	-I../myapi \

=== modified file 'storage/ndb/src/ndbjtie/utils/mystdint.h'
--- a/storage/ndb/src/ndbjtie/utils/mystdint.h	2010-02-13 08:01:08 +0000
+++ b/storage/ndb/src/ndbjtie/utils/mystdint.h	2010-03-12 09:30:44 +0000
@@ -43,11 +43,7 @@
  * definitions should add and use corresponding JTie type mapping aliases.
  */
 
-// XXX bad hack: have autoconf set HAVE_STDINT_H
-// (VC7 = VS2003 = 1310, VC8 = VS2005 = 1400, VC9 = VS2008 = 1500, ...?):
-#if !defined(_MSC_VER) || (_MSC_VER >= 1600)
-#  define HAVE_STDINT_H 1
-#endif
+#include <ndb_global.h>
 
 #ifdef HAVE_STDINT_H
 


Attachment: [text/bzr-bundle] bzr/jonas@mysql.com-20100312140332-0qdh8xp0qfc5xuqq.bundle
Thread
bzr commit into mysql-5.1-telco-7.1 branch (jonas:3495)Jonas Oreland12 Mar 2010