db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject 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/...
Date Fri, 12 Jan 2007 18:19:45 GMT
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:jbraeuchi@hotmail.com">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();
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message