svn commit: r495677 [2/9] - in /db/ojb/trunk: ./ profile/ src/java/org/apache/ojb/broker/ src/java/org/apache/ojb/broker/accesslayer/ src/java/org/apache/ojb/broker/accesslayer/batch/ src/java/org/apache/ojb/broker/accesslayer/sql/ src/java/org/apache/...

[email protected]
Newsgroups gmane.comp.jakarta.ojb.devel
Message-ID <[email protected]>
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java Fri Jan 12 10:19:39 2007
@@ -31,32 +31,33 @@
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.SystemUtils;
 import org.apache.ojb.broker.Identity;
-import org.apache.ojb.broker.OJBRuntimeException;
 import org.apache.ojb.broker.OptimisticLockException;
 import org.apache.ojb.broker.PersistenceBrokerException;
 import org.apache.ojb.broker.PersistenceBrokerInternal;
 import org.apache.ojb.broker.PersistenceBrokerSQLException;
-import org.apache.ojb.broker.lob.LobHandle;
-import org.apache.ojb.broker.accesslayer.batch.BatchInfo;
 import org.apache.ojb.broker.accesslayer.batch.BatchManager;
+import org.apache.ojb.broker.accesslayer.batch.Batcher;
 import org.apache.ojb.broker.accesslayer.sql.SelectStatement;
 import org.apache.ojb.broker.core.ValueContainer;
+import org.apache.ojb.broker.core.factory.ObjectFactory;
+import org.apache.ojb.broker.lob.LobHandle;
 import org.apache.ojb.broker.metadata.ArgumentDescriptor;
 import org.apache.ojb.broker.metadata.ClassDescriptor;
 import org.apache.ojb.broker.metadata.FieldDescriptor;
-import org.apache.ojb.broker.metadata.JdbcTypesHelper;
-import org.apache.ojb.broker.metadata.ProcedureDescriptor;
 import org.apache.ojb.broker.metadata.JdbcType;
+import org.apache.ojb.broker.metadata.ProcedureDescriptor;
+import org.apache.ojb.broker.metadata.GenericDescriptor;
+import org.apache.ojb.broker.metadata.GenericObject;
 import org.apache.ojb.broker.platforms.Platform;
 import org.apache.ojb.broker.query.BetweenCriteria;
 import org.apache.ojb.broker.query.Criteria;
 import org.apache.ojb.broker.query.ExistsCriteria;
-import org.apache.ojb.broker.query.FieldCriteria;
 import org.apache.ojb.broker.query.InCriterion;
-import org.apache.ojb.broker.query.NullCriteria;
 import org.apache.ojb.broker.query.Query;
 import org.apache.ojb.broker.query.QueryByCriteria;
 import org.apache.ojb.broker.query.SelectionCriteria;
+import org.apache.ojb.broker.query.NullCriteria;
+import org.apache.ojb.broker.query.FieldCriteria;
 import org.apache.ojb.broker.query.SqlCriteria;
 import org.apache.ojb.broker.util.BrokerHelper;
 import org.apache.ojb.broker.util.ExceptionHelper;
@@ -78,7 +79,9 @@
 
     /** The broker in use. */
     protected PersistenceBrokerInternal broker;
+    protected BatchManager batchManager;
     protected Platform platform;
+    protected BrokerHelper helper;
 
     /**
      * constructor is private, use getInstance to get
@@ -87,7 +90,9 @@
     public JdbcAccessImpl(PersistenceBrokerInternal broker)
     {
         this.broker = broker;
+        this.helper = broker.serviceBrokerHelper();
         this.platform = broker.serviceConnectionManager().getSupportedPlatform();
+        this.batchManager = broker.serviceBatchManager();
     }
 
     /**
@@ -101,32 +106,31 @@
         if(log.isDebugEnabled()) log.debug("executeDelete: " + obj);
         final StatementManager sm = broker.serviceStatementManager();
         final String sql = broker.serviceSqlGenerator().getPreparedDeleteStatement(cld).getStatement();
-        final boolean isStoredProcedure = useCallableDeleteStatement(cld);
+        final boolean isStoredProcedure = cld.getDeleteProcedure() != null;
         final ValueContainer[] values;
 
         if(isStoredProcedure)
         {
-            values = extractValuesProcedure(cld, obj, cld.getDeleteProcedure());
+            values = extractValues(cld.getDeleteProcedure(), obj);
         }
         else
         {
             values = extractValuesDelete(cld, obj);
         }
 
-        BatchManager bm = broker.serviceBatchManager();
         /*
         arminw:
         if optimistic locking is used and the jdbc-driver dosn't support
         proper return values, we have to execute the batch and use the
         normal statement execution
         */
-        boolean batchExecution = cld.isLocking() && !bm.getBatchSupportOptimisticLocking();
-        if(!batchExecution && isInBatchMode(cld))
+        boolean batchExecution = cld.isLocking() && !batchManager.getBatchSupportOptimisticLocking();
+        if(!batchExecution && isInBatchMode(cld) && !isStoredProcedure)
         {
-            BatchInfo info = new BatchInfo(sql, cld, BatchInfo.TYPE_OBJECT_DELETE);
+            Batcher batcher = new Batcher.Delete(cld, cld.getDeleteProcedure(), sql);
             try
             {
-                bm.addToBatch(info, values, 1);
+                batchManager.add(batcher, values, 1);
             }
             catch(SQLException e)
             {
@@ -138,22 +142,31 @@
             // arminw: if an object with optimistic locking enabled, can't be handled
             // in batch mode, it's recommended to execute already enqueued batch entries
             // to avoid dependency issues
-            if(batchExecution) bm.executeBatch();
+            if(batchExecution) batchManager.executeBatch();
 
             PreparedStatement stmt = null;
             try
             {
                 stmt = sm.getPreparedStatement(sql, Query.NOT_SCROLLABLE,
                         StatementManager.FETCH_SIZE_NOT_APPLICABLE, isStoredProcedure);
-                bindValues(stmt, values, 1, isStoredProcedure);
+                if(isStoredProcedure)
+                {
+                    bindValues((CallableStatement) stmt, values, 1, cld.getDeleteProcedure());
+                }
+                else
+                {
+                    bindValues(stmt, values, 1);
+                }
                 // TODO: return execution result int value in method
                 if(stmt.executeUpdate() == 0 && cld.isLocking())
                 {
-                    throw new OptimisticLockException("Object has been modified or deleted by someone else", obj);
+                    throw new OptimisticLockException("Delete failed, object of class " + obj.getClass().getName()
+                        + " has been modified by someone else, locking fields: "
+                        + ArrayUtils.toString(cld.getLockingFields()), obj);
                 }
 
                 // Harvest any return values.
-                if(isStoredProcedure) harvestReturnValues(cld.getDeleteProcedure(), obj, stmt);
+                if(isStoredProcedure) harvestReturnValues(cld.getDeleteProcedure(), obj, (CallableStatement) stmt);
             }
             catch(OptimisticLockException e)
             {
@@ -176,6 +189,30 @@
         }
     }
 
+    public int executeDelete(GenericDescriptor descriptor, GenericObject obj)
+    {
+        int result;
+        try
+        {
+            if(descriptor.isBatchable() && isInBatchMode(null))
+            {
+                Batcher batcher = new Batcher.GenericDelete(descriptor, broker);
+                batchManager.add(batcher, obj.getValues(), 1);
+                result = 1;
+            }
+            else
+            {
+                PreparedStatement stmt = descriptor.delete(broker, obj);
+                result = stmt.executeUpdate();
+            }
+        }
+        catch(SQLException e)
+        {
+            throw ExceptionHelper.generateException(e, descriptor.deleteSql(broker), null, obj.getValues(), obj, log);
+        }
+        return result;
+    }
+
     /**
      * performs an INSERT operation against RDBMS.
      *
@@ -187,7 +224,7 @@
         if(log.isDebugEnabled()) log.debug("executeInsert: " + obj);
         final StatementManager sm = broker.serviceStatementManager();
         final String sql = broker.serviceSqlGenerator().getPreparedInsertStatement(cld).getStatement();
-        final boolean isStoredProcedure = useCallableInsertStatement(cld);
+        final boolean isStoredProcedure = cld.getInsertProcedure() != null;
         final ValueContainer[] values;
 
         // BRJ : provide useful defaults for locking fields
@@ -204,25 +241,30 @@
 
         if(isStoredProcedure)
         {
-            values = extractValuesProcedure(cld, obj, cld.getInsertProcedure());
+            values = extractValues(cld.getInsertProcedure(), obj);
         }
         else
         {
-            values = broker.serviceBrokerHelper().getAllRwValues(cld, obj);
+            values = extractValues(cld.getAllRwFields(), obj);
         }
         // if DB Identity columns are used for PK values, we can't use batch
         // updates for object insert
-        if(isInBatchMode(cld))
+        if(isInBatchMode(cld) && !isStoredProcedure)
         {
-            BatchInfo info = new BatchInfo(sql, cld, BatchInfo.TYPE_OBJECT_INSERT);
+            Batcher batcher = new Batcher.Insert(cld, cld.getInsertProcedure(), sql);
             try
             {
-                broker.serviceBatchManager().addToBatch(info, values, 1);
+                batchManager.add(batcher, values, 1);
+                postSequenceProcess(cld, obj);
             }
             catch(SQLException e)
             {
                 throw ExceptionHelper.generateException(e, sql, cld, values, obj, log);
             }
+            catch(SequenceManagerException e)
+            {
+                throw new PersistenceBrokerException("Insert failed! Can't assign value of database identity column", e);
+            }
         }
         else
         {
@@ -232,14 +274,21 @@
                 stmt = sm.getPreparedStatement(sql, Query.NOT_SCROLLABLE,
                         StatementManager.FETCH_SIZE_NOT_APPLICABLE, isStoredProcedure);
 
-                bindValues(stmt, values, 1, isStoredProcedure);
+                if(isStoredProcedure)
+                {
+                    bindValues((CallableStatement) stmt, values, 1, cld.getInsertProcedure());
+                }
+                else
+                {
+                    bindValues(stmt, values, 1);
+                }
                 // TODO: return execution result int value in method
                 stmt.executeUpdate();
                 // perform identity column based autoincrement
                 postSequenceProcess(cld, obj);
 
                 // Harvest any return values.
-                if(isStoredProcedure) harvestReturnValues(cld.getInsertProcedure(), obj, stmt);
+                if(isStoredProcedure) harvestReturnValues(cld.getInsertProcedure(), obj, (CallableStatement) stmt);
             }
             catch(PersistenceBrokerException e)
             {
@@ -260,6 +309,30 @@
         }
     }
 
+    public int executeInsert(GenericDescriptor descriptor, GenericObject obj)
+    {
+        int result;
+        try
+        {
+            if(descriptor.isBatchable() && isInBatchMode(null))
+            {
+                Batcher batcher = new Batcher.GenericInsert(descriptor, broker);
+                batchManager.add(batcher, obj.getValues(), 1);
+                result = 1;
+            }
+            else
+            {
+                PreparedStatement stmt = descriptor.insert(broker, obj);
+                result = stmt.executeUpdate();
+            }
+        }
+        catch(SQLException e)
+        {
+            throw ExceptionHelper.generateException(e, descriptor.insertSql(broker), null, obj.getValues(), obj, log);
+        }
+        return result;
+    }
+
     /**
      *
      */
@@ -269,44 +342,49 @@
         final StatementManager sm = broker.serviceStatementManager();
         final boolean isStoredProcedure = SqlHelper.isStoredProcedure(sql);
         int result = Statement.SUCCESS_NO_INFO;
-        if(isInBatchMode(null))
+        // todo: support batching for common statements
+//        if(isInBatchMode(null) && !isStoredProcedure)
+//        {
+//            Batcher batcher = new Batcher.;
+//            try
+//            {
+//                batchManager.add(batcher, values, 1);
+//            }
+//            catch(SQLException e)
+//            {
+//                throw ExceptionHelper.generateException(e, sql, null, values, null, log);
+//            }
+//        }
+//        else
+//        {
+
+        PreparedStatement stmt = null;
+        try
         {
-            BatchInfo info = new BatchInfo(sql);
-            try
+            stmt = sm.getPreparedStatement(sql, Query.NOT_SCROLLABLE,
+                    StatementManager.FETCH_SIZE_NOT_APPLICABLE, isStoredProcedure);
+            // TODO: check handling of callable sql statement
+            if(isStoredProcedure)
             {
-                broker.serviceBatchManager().addToBatch(info, values, 1);
+                bindValues((CallableStatement) stmt, values, 1, null);
             }
-            catch(SQLException e)
+            else
             {
-                throw ExceptionHelper.generateException(e, sql, null, values, null, log);
+                bindValues(stmt, values, 1);
             }
+            result = stmt.executeUpdate();
         }
-        else
+        catch(PersistenceBrokerException e)
         {
-            PreparedStatement stmt = null;
-            try
-            {
-                stmt = sm.getPreparedStatement(sql, Query.NOT_SCROLLABLE,
-                        StatementManager.FETCH_SIZE_NOT_APPLICABLE, isStoredProcedure);
-                // TODO: check handling of callable sql statement
-                if(values != null)
-                {
-                    bindValues(stmt, values, 1, isStoredProcedure);
-                }
-                result = stmt.executeUpdate();
-            }
-            catch(PersistenceBrokerException e)
-            {
-                throw e;
-            }
-            catch(SQLException e)
-            {
-                throw ExceptionHelper.generateException(e, sql, null, values, null, log);
-            }
-            finally
-            {
-                sm.closeResources(stmt, null);
-            }
+            throw e;
+        }
+        catch(SQLException e)
+        {
+            throw ExceptionHelper.generateException(e, sql, null, values, null, log);
+        }
+        finally
+        {
+            sm.closeResources(stmt, null);
         }
         return result;
     }
@@ -344,7 +422,7 @@
         final StatementManager sm = broker.serviceStatementManager();
         final String sql = broker.serviceSqlGenerator().getPreparedUpdateStatement(cld, fieldsToUpdate).getStatement();
         final ValueContainer[] values;
-        final boolean isStoredProcedure = useCallableUpdateStatement(cld);
+        final boolean isStoredProcedure = cld.getUpdateProcedure() != null;
 
         // we can only update LOB content when it's associated with current tx
         if(cld.hasLobField())
@@ -369,27 +447,26 @@
             arminw:
             TODO: Is it possible to support update procedure only for changed fields, instead always update the whole object?
             */
-            values = extractValuesProcedure(cld, obj, cld.getUpdateProcedure());
+            values = extractValues(cld.getUpdateProcedure(), obj);
         }
         else
         {
             values = extractValuesUpdate(cld, fieldsToUpdate, obj);
         }
 
-        BatchManager bm = broker.serviceBatchManager();
         /*
         arminw:
         if optimistic locking is used and the jdbc-driver dosn't support
         proper return values, we have to execute the batch and use the
         normal statement execution
         */
-        boolean batchExecution = cld.isLocking() && !bm.getBatchSupportOptimisticLocking();
-        if(isInBatchMode(cld) && !batchExecution)
+        boolean batchExecution = cld.isLocking() && !batchManager.getBatchSupportOptimisticLocking();
+        if(isInBatchMode(cld) && !batchExecution && !isStoredProcedure)
         {
-            BatchInfo info = new BatchInfo(sql, cld, BatchInfo.TYPE_OBJECT_UPDATE);
+            Batcher batcher = new Batcher.Update(cld, cld.getUpdateProcedure(), sql);
             try
             {
-                broker.serviceBatchManager().addToBatch(info, values, 1);
+                batchManager.add(batcher, values, 1);
             }
             catch(SQLException e)
             {
@@ -401,20 +478,29 @@
             // arminw: if an object with optimistic locking enabled, can't be handled
             // in batch mode, it's recommended to execute already enqueued batch entries
             // to avoid dependency issues
-            if(batchExecution) bm.executeBatch();
+            if(batchExecution) batchManager.executeBatch();
 
             PreparedStatement stmt = null;
             try
             {
                 stmt = sm.getPreparedStatement(sql, Query.NOT_SCROLLABLE,
                         StatementManager.FETCH_SIZE_NOT_APPLICABLE, isStoredProcedure);
-                bindValues(stmt, values, 1, isStoredProcedure);
+                if(isStoredProcedure)
+                {
+                    bindValues((CallableStatement) stmt, values, 1, cld.getUpdateProcedure());
+                }
+                else
+                {
+                    bindValues(stmt, values, 1);
+                }
                 if((stmt.executeUpdate() == 0) && cld.isLocking()) //BRJ
                 {
-                    throw new OptimisticLockException("Object has been modified by someone else", obj);
+                    throw new OptimisticLockException("Update failed, object of class " + obj.getClass().getName()
+                        + " has been modified by someone else, locking fields: "
+                        + ArrayUtils.toString(cld.getLockingFields()), obj);
                 }
                 // Harvest any return values.
-                harvestReturnValues(cld.getUpdateProcedure(), obj, stmt);
+                if(isStoredProcedure) harvestReturnValues(cld.getUpdateProcedure(), obj, (CallableStatement) stmt);
             }
             catch(OptimisticLockException e)
             {
@@ -438,6 +524,30 @@
         }
     }
 
+    public int executeUpdate(GenericDescriptor descriptor, GenericObject obj)
+    {
+        int result;
+        try
+        {
+            if(descriptor.isBatchable() && isInBatchMode(null))
+            {
+                Batcher batcher = new Batcher.GenericUpdate(descriptor, broker);
+                batchManager.add(batcher, obj.getValues(), 1);
+                result = 1;
+            }
+            else
+            {
+                PreparedStatement stmt = descriptor.update(broker, obj);
+                result = stmt.executeUpdate();
+            }
+        }
+        catch(SQLException e)
+        {
+            throw ExceptionHelper.generateException(e, descriptor.deleteSql(broker), null, obj.getValues(), obj, log);
+        }
+        return result;
+    }
+
     /**
      * @see JdbcAccess#doesExist(org.apache.ojb.broker.metadata.ClassDescriptor, Object)
      */
@@ -448,11 +558,11 @@
         ValueContainer[] values;
         if(objectOrIdentity instanceof Identity)
         {
-            values = broker.serviceBrokerHelper().getKeyValues(cld, (Identity) objectOrIdentity);
+            values = helper.getKeyValues(cld, (Identity) objectOrIdentity, true);
         }
         else
         {
-            values = broker.serviceBrokerHelper().getKeyValues(cld, objectOrIdentity);
+            values = extractValues(cld.getPkFields(), objectOrIdentity);
         }
         StatementManager sm = broker.serviceStatementManager();
         PreparedStatement stmt = null;
@@ -460,7 +570,7 @@
         try
         {
             stmt = sm.getPreparedStatement(sql, false, StatementManager.FETCH_SIZE_NOT_APPLICABLE, false);
-            bindValues(stmt, values, 1, false);
+            bindValues(stmt, values, 1);
             rs = stmt.executeQuery();
             result = rs.next();
         }
@@ -553,7 +663,7 @@
             {
                 sql = broker.serviceSqlGenerator().getPreparedSelectStatement(query, cld);
             }
-            final boolean callableStmt = SqlHelper.isStoredProcedure(sql.getStatement());
+            final boolean callableStmt = sql.isStoredProcedure();
             stmt = stmtManager.getPreparedStatement(sql.getStatement(),
                     scrollable, queryFetchSize, callableStmt);
             if(callableStmt)
@@ -618,13 +728,13 @@
                 // Query implemented as a stored procedure, which must return a result set.
                 // Query sytax is: { ?= call PROCEDURE_NAME(?,...,?)}
                 platform.registerOutResultSet((CallableStatement) stmt, 1);
-                bindValues(stmt, values, 2, isStoredprocedure);
+                bindValues((CallableStatement) stmt, values, 2, null);
                 stmt.execute();
                 rs = (ResultSet) ((CallableStatement) stmt).getObject(1);
             }
             else
             {
-                bindValues(stmt, values, 1, isStoredprocedure);
+                bindValues(stmt, values, 1);
                 rs = stmt.executeQuery();
             }
 
@@ -651,6 +761,11 @@
                 {
                     return false;
                 }
+
+                public boolean isStoredProcedure()
+                {
+                    return false;
+                }
             });
         }
         catch(PersistenceBrokerException e)
@@ -683,61 +798,169 @@
      * @return the materialized object, null if no matching row was found or if
      *         any error occured.
      */
-    public Object materializeObject(ClassDescriptor cld, Identity oid)
+    public Object materializeObject(final ClassDescriptor cld, final Identity oid)
+            throws PersistenceBrokerException
+    {
+        Object result;
+        SelectStatement sql = broker.serviceSqlGenerator().getPreparedSelectByPkStatement(cld);
+        final boolean callableStmt = sql.isStoredProcedure();
+        if(callableStmt)
+        {
+            result = materializeObjectProcedure(sql, cld, oid);
+        }
+        else
+        {
+            result = materializeObjectNormal(sql, cld, oid);
+        }
+        return result;
+    }
+
+    private Object materializeObjectNormal(final SelectStatement sql, final ClassDescriptor cld, final Identity oid)
             throws PersistenceBrokerException
     {
         final StatementManager sm = broker.serviceStatementManager();
-        SelectStatement sql = null;
         ValueContainer[] values = null;
         ResultSet rs = null;
         PreparedStatement stmt = null;
         Object result = null;
         try
         {
-            sql = broker.serviceSqlGenerator().getPreparedSelectByPkStatement(cld);
-            final boolean callableStmt = useCallableSelectByPKStatement(cld);
             stmt = sm.getPreparedStatement(sql.getStatement(), Query.NOT_SCROLLABLE,
-                    StatementManager.FETCH_SIZE_NOT_APPLICABLE);
-            values = broker.serviceBrokerHelper().getKeyValues(cld, oid);
-            if(callableStmt)
+                    StatementManager.FETCH_SIZE_NOT_APPLICABLE, false);
+            values = helper.getKeyValues(cld, oid, true);
+            bindValues(stmt, values, 1);
+            rs = stmt.executeQuery();
+            if(rs != null)
             {
-                // First argument is the result set
-                platform.registerOutResultSet((CallableStatement) stmt, 1);
-                bindValues(stmt, values, 2, callableStmt);
-                // If this is a stored procedure call, first argument is ResultSet
-                stmt.execute();
-                rs = (ResultSet) ((CallableStatement) stmt).getObject(1);
+                // data available read object, else return null
+                ResultSetAndStatement rs_stmt = new ResultSetAndStatement(broker, stmt, rs, sql);
+                if (rs.next())
+                {
+                    Map row = new HashMap();
+                    RowReader rowReader = broker.getRowReaderFor(cld);
+                    rowReader.readObjectArrayFrom(rs_stmt, row);
+                    // read enclosing class reference first
+                    Object enclosingObj = broker.materializeEnclosingClassReference(cld, row);
+                    result = rowReader.readObjectFrom(row, enclosingObj);
+                }
+                // close resources
+                rs_stmt.close();
             }
-            else
+        }
+        catch(PersistenceBrokerException e)
+        {
+            // release resources on exception
+            sm.closeResources(stmt, rs);
+            log.error("PersistenceBrokerException during the execution of materializeObject: " + e.getMessage(), e);
+            throw e;
+        }
+        catch(SQLException e)
+        {
+            // release resources on exception
+            sm.closeResources(stmt, rs);
+            throw ExceptionHelper.generateException(e, sql.getStatement(), cld, values, null, log);
+        }
+        return result;
+    }
+
+    private Object materializeObjectProcedure(final SelectStatement sql, final ClassDescriptor cld,
+                                              final Identity oid) throws PersistenceBrokerException
+    {
+        final StatementManager sm = broker.serviceStatementManager();
+        ValueContainer[] values = null;
+        ResultSet rs = null;
+        CallableStatement cs = null;
+        Object result = null;
+        try
+        {
+            cs = (CallableStatement) sm.getPreparedStatement(sql.getStatement(), Query.NOT_SCROLLABLE,
+                    StatementManager.FETCH_SIZE_NOT_APPLICABLE, true);
+            values = helper.getKeyValues(cld, oid, true);
+            int index = 1;
+            ProcedureDescriptor procedure = cld.getSelectByPKProcedure();
+            boolean useResultSet = procedure.hasReturnValue();
+            if(useResultSet)
+            {
+                platform.registerOutResultSet(cs, index);
+                if(log.isDebugEnabled()) log.debug("[SP] Register OUT ResultSet a index " + index);
+                ++index;
+            }
+            List args = procedure.getArguments();
+            for(int i = 0; i < args.size(); i++)
             {
-                bindValues(stmt, values, 1, callableStmt);
-                rs = stmt.executeQuery();
+                ArgumentDescriptor arg =  (ArgumentDescriptor) args.get(i);
+                if(arg.isInParameter())
+                {
+                    if(arg.isConstant())
+                    {
+                        setObjectForStatement(cs, index, arg.getValue(null), arg.getJdbcType().getType());
+                    }
+                    else
+                    {
+                        ValueContainer v = values[i];
+                        setObjectForStatement(cs, index, v.getValue(), v.getJdbcType().getType());
+                    }
+                    if(log.isDebugEnabled()) log.debug("[SP] Register IN parameter at index " + index);
+                    ++index;
+                }
+                else
+                {
+                    cs.registerOutParameter(index, arg.getJdbcType().getType());
+                    ++index;
+                    if(log.isDebugEnabled()) log.debug("[SP] Register OUT parameter at index " + index);
+                }
             }
-            // data available read object, else return null
-            ResultSetAndStatement rs_stmt = new ResultSetAndStatement(broker, stmt, rs, sql);
-            if (rs.next())
-            {
-                Map row = new HashMap();
-                RowReader rowReader = broker.getRowReaderFor(cld);
-                rowReader.readObjectArrayFrom(rs_stmt, row);
-                // read enclosing class reference first
-                Object enclosingObj = broker.materializeEnclosingClassReference(cld, row);
-                result = rowReader.readObjectFrom(row, enclosingObj);
+
+            cs.execute();
+
+            if(useResultSet)
+            {
+                rs = (ResultSet) cs.getObject(1);
+                if(rs != null)
+                {
+                    // data available read object, else return null
+                    ResultSetAndStatement rs_stmt = new ResultSetAndStatement(broker, cs, rs, sql);
+                    if (rs.next())
+                    {
+                        Map row = new HashMap();
+                        RowReader rowReader = broker.getRowReaderFor(cld);
+                        rowReader.readObjectArrayFrom(rs_stmt, row);
+                        // read enclosing class reference first
+                        Object enclosingObj = broker.materializeEnclosingClassReference(cld, row);
+                        result = rowReader.readObjectFrom(row, enclosingObj);
+                    }
+                    // close resources
+                    rs_stmt.close();
+                }
+            }
+            else // use OUT parameter to materialize object
+            {
+                ObjectFactory factory = broker.getConfiguration().getObjectFactory();
+                Object target = factory.newInstance(cld, null, null);
+                harvestReturnValues(procedure, target, cs);
+                // TODO: could this cause side-effects? Better solution?
+                // check if the result is non null
+                if(helper.hasNullPKField(cld, target))
+                {
+                    result = null;
+                }
+                else
+                {
+                    result = target;
+                }
             }
-            // close resources
-            rs_stmt.close();
         }
         catch(PersistenceBrokerException e)
         {
             // release resources on exception
-            sm.closeResources(stmt, rs);
+            sm.closeResources(cs, rs);
             log.error("PersistenceBrokerException during the execution of materializeObject: " + e.getMessage(), e);
             throw e;
         }
         catch(SQLException e)
         {
             // release resources on exception
-            sm.closeResources(stmt, rs);
+            sm.closeResources(cs, rs);
             throw ExceptionHelper.generateException(e, sql.getStatement(), cld, values, null, log);
         }
         return result;
@@ -754,7 +977,7 @@
     {
         ValueContainer[] result;
         // parameters for WHERE-clause pk
-        result = broker.serviceBrokerHelper().getKeyValues(cld, obj);
+        result = extractValues(cld.getPkFields(), obj);
         // parameter for discriminator
         FieldDescriptor discriminatorFd = cld.getDiscriminatorField();
         if(discriminatorFd != null && !discriminatorFd.isPrimaryKey())
@@ -763,7 +986,7 @@
         }
         if(cld.isLocking())
         {
-            result = addValues(result, broker.serviceBrokerHelper().getCurrentLockingValues(cld, obj));
+            result = addValues(result, extractValues(cld.getLockingFields(), obj));
         }
         return result;
     }
@@ -781,38 +1004,19 @@
     protected ValueContainer[] extractValuesUpdate(ClassDescriptor cld, FieldDescriptor[] fields, Object obj)
     {
         ValueContainer[] lockingValuesOld = null;
-        BrokerHelper helper = broker.serviceBrokerHelper();
-
         if(cld.isLocking())
         {
             // lookup current locking values needed below for where-clause
-            lockingValuesOld = helper.getCurrentLockingValues(cld, obj);
+            lockingValuesOld = extractValues(cld.getLockingFields(), obj);
             // update the locking values
             updateLockingValues(cld, obj);
         }
 
         // parameters for SET-clause, all specified fields
-        ValueContainer[] result = helper.getValuesForObject(fields, obj, true);
-
-//        if(cld.isLocking())
-//        {
-//            FieldDescriptor[] lockingFields = cld.getLockingFields();
-//            for(int i = 0; i < lockingFields.length; i++)
-//            {
-//                FieldDescriptor lockingField = lockingFields[i];
-//                // TODO: If a database based lock increment column is used, how does OJB re-read the updated locking columns from the DB?
-//                // only locking fields controlled be OJB needs update, else columns will be updated by DB
-//                if(lockingField.isUpdateLock())
-//                {
-//                    ValueContainer[] tmp = helper.getValuesForObject(new FieldDescriptor[]{lockingField}, obj, true);
-//                    // add to SET-clause
-//                    result = addValues(result, tmp);
-//                }
-//            }
-//        }
+        ValueContainer[] result = extractValues(fields, obj);
 
         // parameters for WHERE-clause pk
-        result = addValues(result, helper.getKeyValues(cld, obj));
+        result = addValues(result, extractValues(cld.getPkFields(), obj));
 
         // parameters for WHERE-clause locking
         if(cld.isLocking())
@@ -832,15 +1036,13 @@
      */
     protected ValueContainer[] extractValues(FieldDescriptor[] fields, Object source)
     {
-        return broker.serviceBrokerHelper().getValuesForObject(fields, source, true);
+        return helper.getValues(fields, source, true);
     }
 
     /**
      * Returns all fields that represents a call to a procedure or
      * user-defined function.
      *
-     * @param cld the class descriptor of the object that triggered the
-     * invocation of the procedure or user-defined function.
      * @param obj the object that triggered the invocation of the procedure
      * or user-defined function.
      * @param proc the procedure descriptor that provides information about
@@ -848,24 +1050,16 @@
      * user-defined function
      * @return The values used in the procedure.
      */
-    protected ValueContainer[] extractValuesProcedure(ClassDescriptor cld, Object obj, ProcedureDescriptor proc)
+    protected ValueContainer[] extractValues(ProcedureDescriptor proc, Object obj)
     {
         List result = new ArrayList();
-        // If we have a return value, then register it.
-        if((proc.hasReturnValue()))
-        {
-            result.add(new ValueContainer(null, proc.getReturnValueFieldRef().getJdbcType(), true));
-        }
-
         // Process all of the arguments.
         Iterator iterator = proc.getArguments().iterator();
         while(iterator.hasNext())
         {
             ArgumentDescriptor arg = (ArgumentDescriptor) iterator.next();
             Object val = arg.getValue(obj);
-            int jdbcType = arg.getJdbcType();
-            result.add(new ValueContainer(val, JdbcTypesHelper.getJdbcTypeByTypesIndex(new Integer(jdbcType)),
-                    arg.getIsReturnedByProcedure()));
+            result.add(new ValueContainer(val, arg.getJdbcType(), arg.isInParameter(), arg.isOutParameter()));
         }
         return (ValueContainer[]) result.toArray(new ValueContainer[result.size()]);
     }
@@ -907,43 +1101,41 @@
      * @param proc the procedure descriptor that provides info about the procedure
      * that was invoked.
      * @param obj the object that was persisted
-     * @param stmt the statement that was used to persist the object.
+     * @param callable the statement that was used to persist the object.
      * @throws org.apache.ojb.broker.PersistenceBrokerSQLException if a problem occurs.
      */
     protected void harvestReturnValues(
             ProcedureDescriptor proc,
             Object obj,
-            PreparedStatement stmt)
+            CallableStatement callable)
             throws PersistenceBrokerSQLException
     {
         // If the procedure descriptor is null or has no return values or
         // if the statement is not a callable statment, then we're done.
-        if((proc == null) || (!proc.hasReturnValues()))
+        if((proc != null))
         {
-            return;
-        }
-        // Set up the callable statement
-        CallableStatement callable = (CallableStatement) stmt;
-        // This is the index that we'll use to harvest the return value(s).
-        int index = 1;
-        // If the proc has a return value, then try to harvest it.
-        if(proc.hasReturnValue())
-        {
-            // Harvest the value.
-            this.harvestReturnValue(obj, callable, proc.getReturnValueFieldRef(), index);
-            // Increment the index
-            index++;
-        }
-        // Check each argument.  If it's returned by the procedure, then harvest the value.
-        Iterator iter = proc.getArguments().iterator();
-        while(iter.hasNext())
-        {
-            ArgumentDescriptor arg = (ArgumentDescriptor) iter.next();
-            if(arg.getIsReturnedByProcedure())
+            // This is the index that we'll use to harvest the return value(s).
+            int index = 1;
+            // Check each argument.  If it's returned by the procedure, then harvest the value.
+            Iterator iter = proc.getArguments().iterator();
+            while(iter.hasNext())
             {
-                this.harvestReturnValue(obj, callable, arg.getFieldRef(), index);
+                ArgumentDescriptor arg = (ArgumentDescriptor) iter.next();
+                if(arg.isOutParameter())
+                {
+//                    System.out.println("stmt: " + callable);
+//                    try
+//                    {
+//                        System.out.println("index=" + index + ", value=" + callable.getObject(index));
+//                    }
+//                    catch(SQLException e)
+//                    {
+//                        e.printStackTrace();
+//                    }
+                    this.harvestReturnValue(obj, callable, arg.getFieldRef(), index);
+                }
+                index++;
             }
-            index++;
         }
     }
 
@@ -992,7 +1184,7 @@
     {
         // TODO: refactor auto-increment handling, auto-increment should only be supported by PK fields?
         // FieldDescriptor[] fields = cld.getPkFields();
-        FieldDescriptor[] fields = cld.getFieldDescriptor(false);
+        FieldDescriptor[] fields = cld.getAutoIncrementFields();
         FieldDescriptor field;
         for(int i = 0; i < fields.length; i++)
         {
@@ -1002,7 +1194,7 @@
                 Object value = field.getPersistentField().get(target);
                 if(broker.serviceBrokerHelper().representsNull(field, value))
                 {
-                    Object id = broker.serviceSequenceManager().getUniqueValue(field);
+                    Object id = broker.serviceSequenceManager().getUniqueValue(broker, field);
                     field.getPersistentField().set(target, id);
                 }
             }
@@ -1014,64 +1206,109 @@
      */
     protected void postSequenceProcess(ClassDescriptor cld, Object target) throws SequenceManagerException
     {
-        // if database Identity Columns are used, query the id from database
-        // other SequenceManager implementations will ignore this call
-        if(cld.useIdentityColumnField())
-        {
-            // execute batch to ensure existance of new id
-            broker.serviceBatchManager().executeBatch();
-            // lookup identity column PK value from DB and set PK in persistent object
-            broker.serviceSequenceManager().afterStore(this, cld, target);
-        }
+        // post insert sequence manager call, e.g. to lookup identity column PK value
+        // from DB and set PK in persistent object
+        broker.serviceSequenceManager().afterStore(broker, this, cld, target);
     }
 
     /**
-     * Binds the values of the object obj to the statements parameters.
+     * Bind values to the statements parameters.
      *
      * @param stmt The {@link java.sql.PreparedStatement} to bind values.
      * @param values The values to bind, if <em>null</em> a {@link NullPointerException} will be thrown.
      * @param index The index to start binding (Default start index should be 1).
-     * @param isCallable If <em>true</em> indicate that the statement is a stored procedure.
      * @return The next index after binding.
      * @throws SQLException
      */
-    public int bindValues(PreparedStatement stmt, ValueContainer[] values, int index, boolean isCallable) throws SQLException
+    public int bindValues(PreparedStatement stmt, ValueContainer[] values, int index) throws SQLException
     {
-        if(values == null) return index;
-
         ValueContainer value = null;
-        try
+        if(values != null)
         {
-            for(int i = 0; i < values.length; i++)
+            try
             {
-                value = values[i];
-                if(isCallable)
+                for(int i = 0; i < values.length; i++)
                 {
-                    try
-                    {
-                        if(value.isProcedureOutParameter())
-                        {
-                            CallableStatement cs = (CallableStatement) stmt;
-                            cs.registerOutParameter(index, value.getJdbcType().getType());
-                        }
-                    }
-                    catch(ClassCastException e)
-                    {
-                        throw new OJBRuntimeException("Class cast error while bind values", e);
-                    }
+                    value = values[i];
+                    setObjectForStatement(stmt, index, value.getValue(), value.getJdbcType().getType());
+                    index++;
                 }
-                setObjectForStatement(stmt, index, value.getValue(), value.getJdbcType().getType());
+            }
+            catch(SQLException e)
+            {
+                String eol = SystemUtils.LINE_SEPARATOR;
+                log.error("Error while try to bind value '" + index + "', the value is: " + value
+                        + eol + "Values to bind are: " + ArrayUtils.toString(values));
+                throw e;
+            }
+        }
+        return index;
+    }
+
+    /**
+     * Bind values to the callable statement IN/OUT parameter.
+     *
+     * @param cs The {@link java.sql.CallableStatement} to bind values.
+     * @param values The values to bind.
+     * @param index The index to start binding (Default start index should be 1).
+     * @param descriptor The {@link org.apache.ojb.broker.metadata.ProcedureDescriptor}
+     * or <em>null</em> if it doesn't exist.
+     * @return The next index after binding.
+     * @throws SQLException
+     */
+    public int bindValues(CallableStatement cs, ValueContainer[] values,
+                   int index, ProcedureDescriptor descriptor) throws SQLException
+    {
+        ValueContainer value;
+        if(descriptor != null)
+        {
+            if(index == 1 && descriptor.hasReturnValue())
+            {
+                platform.registerOutResultSet(cs, index);
+                if(log.isDebugEnabled()) log.debug("[SP] Register OUT ResultSet a index " + index);
+                ++index;
+            }
+        }
+        if(values != null)
+        {
+            for(int i = 0; i < values.length; i++)
+            {
+                value = values[i];
+                bindValueForProcedure(cs, value, index);
                 index++;
             }
         }
+        return index;
+    }
+
+    /**
+     * Binds the values of the object obj to the statements parameters.
+     *
+     * @param cs The {@link java.sql.CallableStatement} to bind value.
+     * @param value The value to bind.
+     * @throws SQLException
+     */
+    private void bindValueForProcedure(final CallableStatement cs, final ValueContainer value, int index)
+            throws SQLException
+    {
+        try
+        {
+            if(value.isProcedureOutParameter())
+            {
+                cs.registerOutParameter(index, value.getJdbcType().getType());
+                if(log.isDebugEnabled()) log.debug("[SP] Register OUT parameter at index " + index);
+            }
+            else if(value.isProcedureInParameter())
+            {
+                setObjectForStatement(cs, index, value.getValue(), value.getJdbcType().getType());
+                if(log.isDebugEnabled()) log.debug("[SP] Register IN parameter at index " + index);
+            }
+        }
         catch(SQLException e)
         {
-            String eol = SystemUtils.LINE_SEPARATOR;
-            log.error("Error while try to bind value '" + index + "', the value are: " + value
-                    + eol + "Values to bind are: " + ArrayUtils.toString(values));
+            log.error("Error while try to bind stored procedure value at index '" + index + "', the value is: " + value);
             throw e;
         }
-        return index;
     }
 
     /**
@@ -1139,48 +1376,6 @@
         return scrollable;
     }
 
-//    /**
-//     * A class is batchable when <br/>
-//     * - PB is in tx<br/>
-//     * - batch mode is enabled<br/>
-//     * - class allows batch mode<br/>
-//     * <p>
-//     * Additionally this method checks if this class use optimistic locking and if the
-//     * {@link org.apache.ojb.broker.accesslayer.batch.BatchManager#getBatchSupportOptimisticLocking}
-//     * flag was set. If both was <em>true</em> the batch
-//     * will be executed and <em>false</em> will be returned. Except when in class-descriptor
-//     * {@link org.apache.ojb.broker.metadata.ClassDescriptor#setBatchable(boolean)} <em>false</em>
-//     * was set, in that case the user is responsible to execute the batch by himself.
-//     * </p>
-//     */
-//    protected boolean isBatchableAndCheckOptimisticLockingExecute(ClassDescriptor cld) throws SQLException
-//    {
-//        boolean result = false;
-//        // first we check if we are in batch mode
-//        if(cld.isBatchable() && isInBatchMode(cld))
-//        {
-//            // if object use optimistic locking and we don't want
-//            // include those objects in batch
-//            if(!broker.serviceBatchManager().getBatchSupportOptimisticLocking() && cld.isLocking())
-//            {
-//                // if object is batchable we automatic handle the
-//                // batch and execute batch, else user is responsible for doing this
-//                result = false;
-//                broker.serviceBatchManager().executeBatch();
-//            }
-//            else
-//            {
-//                result = true;
-//            }
-//        }
-//        return result;
-//    }
-//
-//    protected boolean needsBatchExecuteForOptimisticLocking(ClassDescriptor cld)
-//    {
-//        return cld.isLocking() && !broker.serviceBatchManager().getBatchSupportOptimisticLocking();
-//    }
-
     /**
      * Returns <em>true</em> if batch mode is enabled and allowed for
      * the specified {@link org.apache.ojb.broker.metadata.ClassDescriptor}.
@@ -1191,45 +1386,11 @@
     protected boolean isInBatchMode(ClassDescriptor cld)
     {
         return broker.isInTransaction()
-                && broker.serviceBatchManager().isBatchMode()
+                && batchManager.isBatchMode()
                 && (cld == null || cld.isBatchable());
     }
 
-    /**
-     * Answer 'false' if a PreparedStatement has to be used
-     * <br>'true' for a CallableStatement
-     */
-    protected boolean useCallableDeleteStatement(ClassDescriptor cld)
-    {
-        return cld.getDeleteProcedure() != null;
-    }
-
-    /**
-     * Answer 'false' if a PreparedStatement has to be used
-     * <br>'true' for a CallableStatement
-     */
-    protected boolean useCallableInsertStatement(ClassDescriptor cld)
-    {
-        return cld.getInsertProcedure() != null;
-    }
 
-    /**
-     * Answer 'false' if a PreparedStatement has to be used
-     * <br>'true' for a CallableStatement
-     */
-    protected boolean useCallableSelectByPKStatement(ClassDescriptor cld)
-    {
-        return cld.getSelectByPKProcedure() != null; //&& cld.getSelectByPKProcedure().hasReturnValues();
-    }
-
-    /**
-     * Answer 'false' if a PreparedStatement has to be used
-     * <br>'true' for a CallableStatement
-     */
-    protected boolean useCallableUpdateStatement(ClassDescriptor cld)
-    {
-        return cld.getUpdateProcedure() != null; //&& cld.getUpdateProcedure().hasReturnValues();
-    }
 
     /**
      * bind attribute and value
@@ -1242,7 +1403,8 @@
      * @return
      * @throws java.sql.SQLException
      */
-    private int bindStatementValue(PreparedStatement stmt, int index, Object attributeOrQuery, Object value, ClassDescriptor cld)
+    private int bindStatementValue(final PreparedStatement stmt, int index, final Object attributeOrQuery,
+                                   final Object value, final ClassDescriptor cld)
             throws SQLException
     {
         FieldDescriptor fld = null;
@@ -1292,74 +1454,6 @@
     }
 
     /**
-     * bind SelectionCriteria
-     *
-     * @param stmt the PreparedStatement
-     * @param index the position of the parameter to bind
-     * @param crit the Criteria containing the parameter
-     * @param cld the ClassDescriptor
-     * @return next index for PreparedStatement
-     */
-    private int bindStatement(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld) throws SQLException
-    {
-        return bindStatementValue(stmt, index, crit.getAttribute(), crit.getValue(), cld);
-    }
-
-    /**
-     * bind NullCriteria
-     *
-     * @param stmt the PreparedStatement
-     * @param index the position of the parameter to bind
-     * @param crit the Criteria containing the parameter
-     * @return next index for PreparedStatement
-     */
-    private int bindStatement(PreparedStatement stmt, int index, NullCriteria crit)
-    {
-        return index;
-    }
-
-    /**
-     * bind FieldCriteria
-     *
-     * @param stmt , the PreparedStatement
-     * @param index , the position of the parameter to bind
-     * @param crit , the Criteria containing the parameter
-     * @return next index for PreparedStatement
-     */
-    private int bindStatement(PreparedStatement stmt, int index, FieldCriteria crit)
-    {
-        return index;
-    }
-
-    /**
-     * bind SqlCriteria
-     *
-     * @param stmt the PreparedStatement
-     * @param index the position of the parameter to bind
-     * @param crit the Criteria containing the parameter
-     * @return next index for PreparedStatement
-     */
-    private int bindStatement(PreparedStatement stmt, int index, SqlCriteria crit)
-    {
-        return index;
-    }
-
-    /**
-     * bind BetweenCriteria
-     *
-     * @param stmt the PreparedStatement
-     * @param index the position of the parameter to bind
-     * @param crit the Criteria containing the parameter
-     * @param cld the ClassDescriptor
-     * @return next index for PreparedStatement
-     */
-    private int bindStatement(PreparedStatement stmt, int index, BetweenCriteria crit, ClassDescriptor cld) throws SQLException
-    {
-        index = bindStatementValue(stmt, index, crit.getAttribute(), crit.getValue(), cld);
-        return bindStatementValue(stmt, index, crit.getAttribute(), crit.getValue2(), cld);
-    }
-
-    /**
      * bind InCriteria
      *
      * @param stmt the PreparedStatement
@@ -1368,7 +1462,8 @@
      * @param cld the ClassDescriptor
      * @return next index for PreparedStatement
      */
-    private int bindStatement(PreparedStatement stmt, int index, InCriterion crit, ClassDescriptor cld) throws SQLException
+    private int bindStatement(final PreparedStatement stmt, int index,
+                              final InCriterion crit, final ClassDescriptor cld) throws SQLException
     {
         if(crit.getValue() instanceof Collection)
         {
@@ -1396,7 +1491,8 @@
      * @param cld the ClassDescriptor
      * @return next index for PreparedStatement
      */
-    private int bindStatement(PreparedStatement stmt, int index, ExistsCriteria crit, ClassDescriptor cld)
+    private int bindStatement(final PreparedStatement stmt, int index,
+                              final ExistsCriteria crit, final ClassDescriptor cld)
             throws SQLException
     {
         Query subQuery = (Query) crit.getValue();
@@ -1418,7 +1514,8 @@
     }
 
     /** bind a Query based Select Statement */
-    public int bindStatement(PreparedStatement stmt, Query query, ClassDescriptor cld, int param) throws SQLException
+    public int bindStatement(final PreparedStatement stmt, final Query query,
+                             final ClassDescriptor cld, int param) throws SQLException
     {
         int index;
 
@@ -1435,7 +1532,8 @@
     }
 
     /** bind a Query based Select Statement */
-    protected int bindStatement(PreparedStatement stmt, Criteria crit, ClassDescriptor cld, int index) throws SQLException
+    protected int bindStatement(final PreparedStatement stmt, final Criteria crit,
+                                final ClassDescriptor cld, int index) throws SQLException
     {
         if(crit != null)
         {
@@ -1470,7 +1568,9 @@
      * @param cld the ClassDescriptor
      * @return next index for PreparedStatement
      */
-    private int bindSelectionCriteriaWithExtents(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld) throws SQLException
+    private int bindSelectionCriteriaWithExtents(final PreparedStatement stmt, int index,
+                                                 final SelectionCriteria crit, final ClassDescriptor cld)
+            throws SQLException
     {
         // BRJ : bind once for the criterion's main class
         index = bindSelectionCriteria(stmt, index, crit, cld);
@@ -1493,13 +1593,10 @@
      * @param cld the ClassDescriptor
      * @return next index for PreparedStatement
      */
-    private int bindSelectionCriteria(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld) throws SQLException
+    private int bindSelectionCriteria(final PreparedStatement stmt, int index,
+                                      final SelectionCriteria crit, final ClassDescriptor cld) throws SQLException
     {
-        if(crit instanceof NullCriteria)
-        {
-            index = bindStatement(stmt, index, (NullCriteria) crit);
-        }
-        else if(crit instanceof BetweenCriteria)
+        if(crit instanceof BetweenCriteria)
         {
             index = bindStatement(stmt, index, (BetweenCriteria) crit, cld);
         }
@@ -1507,6 +1604,10 @@
         {
             index = bindStatement(stmt, index, (InCriterion) crit, cld);
         }
+        else if(crit instanceof ExistsCriteria)
+        {
+            index = bindStatement(stmt, index, (ExistsCriteria) crit, cld);
+        }
         else if(crit instanceof SqlCriteria)
         {
             index = bindStatement(stmt, index, (SqlCriteria) crit);
@@ -1515,14 +1616,83 @@
         {
             index = bindStatement(stmt, index, (FieldCriteria) crit);
         }
-        else if(crit instanceof ExistsCriteria)
+        else if(crit instanceof NullCriteria)
         {
-            index = bindStatement(stmt, index, (ExistsCriteria) crit, cld);
+            index = bindStatement(stmt, index, (NullCriteria) crit);
         }
         else
         {
             index = bindStatement(stmt, index, crit, cld);
         }
+        return index;
+    }
+
+    /**
+     * bind SelectionCriteria
+     *
+     * @param stmt the PreparedStatement
+     * @param index the position of the parameter to bind
+     * @param crit the Criteria containing the parameter
+     * @param cld the ClassDescriptor
+     * @return next index for PreparedStatement
+     */
+    private int bindStatement(final PreparedStatement stmt, int index,
+                              final SelectionCriteria crit, final ClassDescriptor cld) throws SQLException
+    {
+        return bindStatementValue(stmt, index, crit.getAttribute(), crit.getValue(), cld);
+    }
+
+    /**
+     * bind BetweenCriteria
+     *
+     * @param stmt the PreparedStatement
+     * @param index the position of the parameter to bind
+     * @param crit the Criteria containing the parameter
+     * @param cld the ClassDescriptor
+     * @return next index for PreparedStatement
+     */
+    private int bindStatement(final PreparedStatement stmt, int index, final BetweenCriteria crit, final ClassDescriptor cld) throws SQLException
+    {
+        index = bindStatementValue(stmt, index, crit.getAttribute(), crit.getValue(), cld);
+        return bindStatementValue(stmt, index, crit.getAttribute(), crit.getValue2(), cld);
+    }
+
+    /**
+     * bind NullCriteria
+     *
+     * @param stmt the PreparedStatement
+     * @param index the position of the parameter to bind
+     * @param crit the Criteria containing the parameter
+     * @return next index for PreparedStatement
+     */
+    private int bindStatement(PreparedStatement stmt, int index, NullCriteria crit)
+    {
+        return index;
+    }
+
+    /**
+     * bind FieldCriteria
+     *
+     * @param stmt , the PreparedStatement
+     * @param index , the position of the parameter to bind
+     * @param crit , the Criteria containing the parameter
+     * @return next index for PreparedStatement
+     */
+    private int bindStatement(PreparedStatement stmt, int index, FieldCriteria crit)
+    {
+        return index;
+    }
+
+    /**
+     * bind SqlCriteria
+     *
+     * @param stmt the PreparedStatement
+     * @param index the position of the parameter to bind
+     * @param crit the Criteria containing the parameter
+     * @return next index for PreparedStatement
+     */
+    private int bindStatement(PreparedStatement stmt, int index, SqlCriteria crit)
+    {
         return index;
     }
 }

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/MtoNCollectionPrefetcher.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/MtoNCollectionPrefetcher.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/MtoNCollectionPrefetcher.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/MtoNCollectionPrefetcher.java Fri Jan 12 10:19:39 2007
@@ -223,11 +223,8 @@
         PersistenceBroker pb = getBroker();
         IdentityFactory idFactory = pb.serviceIdentity();
         ClassDescriptor cld = getOwnerClassDescriptor();
-        Class topLevelClass = pb.getTopLevelClass(cld.getClassOfObject());
-        BrokerHelper helper = pb.serviceBrokerHelper();
         Collection queries = new ArrayList(owners.size());
         Collection idsSubset = new HashSet(owners.size());
-        Object[] fkValues;
         Object owner;
         Identity id;
 
@@ -419,8 +416,8 @@
         IdentityFactory idFactory = pb.serviceIdentity();
         CollectionDescriptor cds = getCollectionDescriptor();
         PersistentField field = cds.getPersistentField();
-        Class ownerTopLevelClass = pb.getTopLevelClass(getOwnerClassDescriptor().getClassOfObject());
-        Class childTopLevelClass = pb.getTopLevelClass(getItemClassDescriptor().getClassOfObject());
+        Class ownerTopLevelClass = getOwnerClassDescriptor().getTopLevelClass();
+        Class childTopLevelClass = getItemClassDescriptor().getTopLevelClass();
         Class collectionClass = cds.getCollectionClass(); // this collection type will be used:
         HashMap childMap = new HashMap();
         HashMap ownerIdsToLists = new HashMap();

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/QueryCustomizerDefaultImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/QueryCustomizerDefaultImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/QueryCustomizerDefaultImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/QueryCustomizerDefaultImpl.java Fri Jan 12 10:19:39 2007
@@ -20,6 +20,7 @@
 
 import org.apache.ojb.broker.PersistenceBroker;
 import org.apache.ojb.broker.metadata.CollectionDescriptor;
+import org.apache.ojb.broker.metadata.DescriptorBase;
 import org.apache.ojb.broker.query.Query;
 import org.apache.ojb.broker.query.QueryByCriteria;
 
@@ -29,11 +30,8 @@
  * @author <a href="mailto:[email protected]">Jakob Braeuchi</a>
  * @version $Id$
  */
-public class QueryCustomizerDefaultImpl implements QueryCustomizer
+public class QueryCustomizerDefaultImpl  extends DescriptorBase implements QueryCustomizer
 {
-
-    private Properties m_attributes = null;
-
 	/**
 	 * Default Constructor
 	 */
@@ -51,59 +49,4 @@
     {
         return aQuery;
     }
-
-    /**
-     * @see org.apache.ojb.broker.metadata.AttributeContainer#getAttributes()
-     */
-    public Properties getAttributes()
-    {
-        return m_attributes;
-    }
-
-    public void addAttributes(Map attributes)
-    {
-        if (m_attributes==null)
-        {
-            m_attributes=new Properties();
-        }
-        m_attributes.putAll(attributes);
-    }
-
-    /**
-     * @see org.apache.ojb.broker.metadata.AttributeContainer#addAttribute(String, String)
-     */
-   public void addAttribute(String attributeName, String attributeValue)
-   {
-        if (attributeName==null)
-        {
-            return;
-        }
-        if (m_attributes==null)
-        {
-            m_attributes=new Properties();
-        }
-       m_attributes.setProperty(attributeName,attributeValue);
-    }
-
-	/* (non-Javadoc)
-	 * @see org.apache.ojb.broker.metadata.AttributeContainer#getAttribute(java.lang.String, java.lang.String)
-	 */
-	public String getAttribute(String attributeName, String defaultValue)
-	{
-        String result = defaultValue;
-        if (m_attributes!=null)
-        {
-            result = m_attributes.getProperty(attributeName, defaultValue);
-        }
-        return result;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.apache.ojb.broker.metadata.AttributeContainer#getAttribute(java.lang.String)
-	 */
-	public String getAttribute(String attributeName)
-	{
-        return this.getAttribute(attributeName,null);
-	}
-
 }

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/ReferencePrefetcher.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/ReferencePrefetcher.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/ReferencePrefetcher.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/ReferencePrefetcher.java Fri Jan 12 10:19:39 2007
@@ -59,7 +59,7 @@
         ObjectReferenceDescriptor ord = getObjectReferenceDescriptor();
         PersistenceBroker pb = getBroker();
         PersistentField field = ord.getPersistentField();
-        Class topLevelClass = pb.getTopLevelClass(ord.getItemClass());
+        Class topLevelClass = ord.getItemClassDescriptor().getTopLevelClass();
         HashMap childrenMap = new HashMap(children.size());
         IdentityFactory idFactory = pb.serviceIdentity();
         Object owner;
@@ -114,7 +114,7 @@
         Collection queries = new ArrayList(owners.size());
         Collection idsSubset = new HashSet(owners.size());
         Iterator iter = owners.iterator();
-        Class topLevelClass = getBroker().getTopLevelClass(ord.getItemClass());
+        Class topLevelClass = ord.getItemClassDescriptor().getTopLevelClass();
         Object[] fkValues;
         Object owner;
         Identity id;

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RelationshipPrefetcherImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RelationshipPrefetcherImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RelationshipPrefetcherImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RelationshipPrefetcherImpl.java Fri Jan 12 10:19:39 2007
@@ -109,7 +109,6 @@
         this.cascadeRetrieve = cascadeRetrieve;
     }
     
-    
     /**
      * Get the values of the fk-target-fields for an obj.
      * @param objOrProxy
@@ -117,8 +116,7 @@
      */
     protected Object[] getFkTargetValuesForObject(Object objOrProxy) throws PersistenceBrokerException
     {
-        PersistenceBroker pb = getBroker();
-        BrokerHelper helper = pb.serviceBrokerHelper();
+        BrokerHelper helper = getBroker().serviceBrokerHelper();
         ObjectReferenceDescriptor rds = getObjectReferenceDescriptor();
         
         ValueContainer[] values = helper.getFkTargetValuesForObject(rds, objOrProxy, false);
@@ -132,12 +130,10 @@
      */
     protected Object[] getFkValuesForObject(Object objOrProxy) throws PersistenceBrokerException
     {
-        PersistenceBroker pb = getBroker();
-        BrokerHelper helper = pb.serviceBrokerHelper();
+        BrokerHelper helper = getBroker().serviceBrokerHelper();
         ObjectReferenceDescriptor rds = getObjectReferenceDescriptor();
 
         ValueContainer[] values = helper.getFkValuesForObject(rds, objOrProxy, false);
         return helper.extractValueArray(values);
     } 
-    
 }

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RowReader.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RowReader.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RowReader.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RowReader.java Fri Jan 12 10:19:39 2007
@@ -26,7 +26,7 @@
  *
  * @version $Id$
  */
-public interface RowReader extends Serializable
+public interface RowReader
 {
     static final long serialVersionUID = -1283322922537162249L;
 

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RowReaderDefaultImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RowReaderDefaultImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RowReaderDefaultImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RowReaderDefaultImpl.java Fri Jan 12 10:19:39 2007
@@ -25,7 +25,7 @@
 import org.apache.commons.beanutils.ConvertUtils;
 import org.apache.commons.collections.map.ListOrderedMap;
 import org.apache.ojb.broker.PersistenceBrokerException;
-import org.apache.ojb.broker.core.factory.ObjectFactory;
+import org.apache.ojb.broker.PersistenceConfiguration;
 import org.apache.ojb.broker.metadata.ClassDescriptor;
 import org.apache.ojb.broker.metadata.CreationDescriptor;
 import org.apache.ojb.broker.metadata.CreationParameter;
@@ -41,8 +41,8 @@
 
 public class RowReaderDefaultImpl implements RowReader
 {
-    /** Unique ID for serialization purposes */
-    private static final long serialVersionUID = -6167325067758522342L;
+//    /** Unique ID for serialization purposes */
+//    private static final long serialVersionUID = -6167325067758522342L;
     /**
      * Used as key in result set row map.
      */
@@ -53,13 +53,11 @@
     private static final Object[] NO_ARGS = {};
 
     private ClassDescriptor classDescriptor;
+    private PersistenceConfiguration pc;
 
-    /** The object factory to be used by this row reader for classes that require it */
-    private transient ObjectFactory factory;
-
-    public RowReaderDefaultImpl(ObjectFactory factory, ClassDescriptor classDescriptor)
+    public RowReaderDefaultImpl(PersistenceConfiguration pc, ClassDescriptor classDescriptor)
     {
-        this.factory         = factory;
+        this.pc = pc;
         this.classDescriptor = classDescriptor;
     }
 
@@ -204,7 +202,7 @@
                 }
             }
         }
-        return factory.newInstance(classDesc, args, enclosingObj);
+        return pc.getObjectFactory().newInstance(classDesc, args, enclosingObj);
     }
 
     /**
@@ -255,45 +253,30 @@
     public void readObjectArrayFrom(ResultSetAndStatement rs_stmt, Map row)
     {
         FieldDescriptor[] fields;
-/*
-arminw:
-TODO: this feature doesn't work, so remove this in future
-*/
-        if (classDescriptor.getSuperClass() != null)
-        {
-            /**
-             * treeder
-             * append super class fields if exist
-             */
-            fields = classDescriptor.getFieldDescriptorsInHeirarchy();
+        String ojbDiscriminator = extractOjbConcreteClass(classDescriptor, rs_stmt.m_rs, row);
+        /*
+        arminw:
+        if multiple classes were mapped to the same table, lookup the concrete
+        class and use these fields, attach ojbDiscriminator in row map for later use
+        */
+        if(ojbDiscriminator != null)
+        {
+            ClassDescriptor cld = classDescriptor.getRepository().getDescriptorForDiscriminator(classDescriptor,ojbDiscriminator);
+            row.put(OJB_DISCRIMINATOR_KEY, cld.getClassOfObject());
+            fields = cld.getFieldDescriptor(true);
         }
         else
         {
-            String ojbDiscriminator = extractOjbConcreteClass(classDescriptor, rs_stmt.m_rs, row);
-            /*
-            arminw:
-            if multiple classes were mapped to the same table, lookup the concrete
-            class and use these fields, attach ojbDiscriminator in row map for later use
-            */
-            if(ojbDiscriminator != null)
+            String ojbClass = SqlHelper.getOjbClassName(rs_stmt);
+            if (ojbClass != null)
             {
-                ClassDescriptor cld = classDescriptor.getRepository().getDescriptorForDiscriminator(classDescriptor,ojbDiscriminator);
+                ClassDescriptor cld = classDescriptor.getRepository().getDescriptorFor(ojbClass);
                 row.put(OJB_DISCRIMINATOR_KEY, cld.getClassOfObject());
                 fields = cld.getFieldDescriptor(true);
             }
             else
             {
-                String ojbClass = SqlHelper.getOjbClassName(rs_stmt);
-                if (ojbClass != null)
-                {
-                    ClassDescriptor cld = classDescriptor.getRepository().getDescriptorFor(ojbClass);
-                    row.put(OJB_DISCRIMINATOR_KEY, cld.getClassOfObject());
-                    fields = cld.getFieldDescriptor(true);
-                }
-                else
-                {
-                    fields = classDescriptor.getFieldDescriptor(true);
-                }           
+                fields = classDescriptor.getFieldDescriptor(true);
             }
         }
         readValuesFrom(rs_stmt, row, fields);

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java Fri Jan 12 10:19:39 2007
@@ -198,7 +198,7 @@
     {
         if (m_itemTopLevelClass == null)
         {
-            m_itemTopLevelClass = getBroker().getTopLevelClass(getQueryObject().getClassDescriptor().getClassOfObject());
+            m_itemTopLevelClass = getQueryObject().getClassDescriptor().getTopLevelClass();
         }
         return m_itemTopLevelClass;
     }

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java Fri Jan 12 10:19:39 2007
@@ -20,6 +20,7 @@
 import java.sql.Statement;
 
 import org.apache.ojb.broker.PersistenceBrokerException;
+import org.apache.ojb.broker.platforms.Platform;
 
 /**
  * This class is responsible for creation, closing of all kind of
@@ -33,20 +34,19 @@
     /**
      * fetchSize hint marking that setting fetch size for current statement is N/A.
      */
-    int FETCH_SIZE_NOT_APPLICABLE = -1;
+    public static final int FETCH_SIZE_NOT_APPLICABLE = -1;
     /**
      * fetchSize hint marking that there is no statement-level explicit override.
      */
-    int FETCH_SIZE_NOT_EXPLICITLY_SET = 0;
+    public static final int FETCH_SIZE_NOT_EXPLICITLY_SET = 0;
 
     /**
      * Close the specified resources. It's mandatory to use this method for all
      * {@link java.sql.Statement} and {@link java.sql.ResultSet} instances internally
-     * obtained by OJB, because calls to {@link org.apache.ojb.broker.platforms.Platform}
-     * are done on resource close.
+     * obtained by OJB.
      *
      * @param stmt The statement to close.
-     * @param rs   The ResultSet to close.
+     * @param rs The ResultSet to close.
      */
     public void closeResources(Statement stmt, ResultSet rs);
 
@@ -76,7 +76,9 @@
     public void setUseStatementCache(boolean useStatementCache);
 
     /**
-     * return a generic Statement for the given ClassDescriptor
+     * Returns a generic statement.
+     *
+     * @see #closeResources(java.sql.Statement, java.sql.ResultSet)
      */
     Statement getGenericStatement(boolean scrollable) throws PersistenceBrokerException;
 
@@ -91,6 +93,7 @@
      * callable statement.
      * @return The generated statement.
      * @throws PersistenceBrokerException
+     * @see #closeResources(java.sql.Statement, java.sql.ResultSet)
      */
     PreparedStatement getPreparedStatement(String sql, boolean scrollable, int explicitFetchSizeHint, boolean callableStmt)
             throws PersistenceBrokerException;
@@ -103,7 +106,15 @@
      * @param explicitFetchSizeHint The statement fetch size.
      * @return The generated statement.
      * @throws PersistenceBrokerException
+     * @see #closeResources(java.sql.Statement, java.sql.ResultSet)
      */
     PreparedStatement getPreparedStatement(String sql, boolean scrollable, int explicitFetchSizeHint)
             throws PersistenceBrokerException;
+
+    /**
+     * Returns the associated database {@link org.apache.ojb.broker.platforms.Platform}.
+     *
+     * @return The database platform.
+     */
+    Platform getPlatform();
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.