You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by br...@apache.org on 2003/03/01 23:19:02 UTC

cvs commit: db-ojb/src/java/org/apache/ojb/broker/accesslayer StatementManager.java

brj         2003/03/01 14:19:02

  Modified:    src/java/org/apache/ojb/broker/accesslayer
                        StatementManager.java
  Log:
  moved get...values to BrokerHelper
  
  Revision  Changes    Path
  1.22      +695 -748  db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java
  
  Index: StatementManager.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- StatementManager.java	2 Feb 2003 03:39:19 -0000	1.21
  +++ StatementManager.java	1 Mar 2003 22:19:02 -0000	1.22
  @@ -54,13 +54,23 @@
    * <http://www.apache.org/>.
    */
   
  +import java.sql.PreparedStatement;
  +import java.sql.ResultSet;
  +import java.sql.SQLException;
  +import java.sql.Statement;
  +import java.sql.Types;
  +import java.util.Collection;
  +import java.util.Enumeration;
  +import java.util.Iterator;
  +import java.util.Map;
  +import java.util.WeakHashMap;
  +
   import org.apache.ojb.broker.Identity;
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.PersistenceBrokerException;
   import org.apache.ojb.broker.PersistenceBrokerSQLException;
   import org.apache.ojb.broker.metadata.ClassDescriptor;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
  -import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
   import org.apache.ojb.broker.platforms.Platform;
   import org.apache.ojb.broker.platforms.PlatformException;
   import org.apache.ojb.broker.platforms.PlatformFactory;
  @@ -78,17 +88,6 @@
   import org.apache.ojb.broker.util.logging.Logger;
   import org.apache.ojb.broker.util.logging.LoggerFactory;
   
  -import java.sql.PreparedStatement;
  -import java.sql.ResultSet;
  -import java.sql.SQLException;
  -import java.sql.Statement;
  -import java.sql.Types;
  -import java.util.Collection;
  -import java.util.Enumeration;
  -import java.util.Iterator;
  -import java.util.Map;
  -import java.util.WeakHashMap;
  -
   /**
    * manages JDBC Connection and Statement resources.
    *
  @@ -97,740 +96,688 @@
    */
   public class StatementManager implements StatementManagerIF
   {
  -    private Logger log = LoggerFactory.getLogger(StatementManager.class);
  +	private Logger log = LoggerFactory.getLogger(StatementManager.class);
   
  -    /** internal table of StatementForClass objects */
  -    private Map statementTable = new WeakHashMap();
  -    /** the associated broker */
  -    private final PersistenceBroker broker;
  -    private Platform platform;
  -    /**
  -     * Used when OJB run in JBoss
  -     * @todo Find a better solution to handle OJB within JBoss
  -     * --> the JCA implementation should solve this problem
  -     */
  -    private boolean m_eagerRelease;
  -    private ConnectionManagerIF conMan;
  -
  -    public StatementManager(final PersistenceBroker pBroker)
  -    {
  -        this.broker = pBroker;
  -        this.conMan = broker.serviceConnectionManager();
  -        m_eagerRelease = conMan.getConnectionDescriptor().getEagerRelease();
  -        platform = PlatformFactory.getPlatformFor(conMan.getConnectionDescriptor());
  -    }
  -
  -    /**
  -     * return a StatementsForClass object for the given ClassDescriptor\
  -     * Note; not important to synchronize completely as a threading issue in this code
  -     * will only result in a little extra code being executed
  -     */
  -    protected StatementsForClassIF getStatementsForClass(ClassDescriptor cds)
  -            throws PersistenceBrokerException
  -    {
  -        StatementsForClassIF sfc = (StatementsForClassIF) statementTable.get(cds);
  -        if (sfc == null)
  -        {
  -            synchronized (statementTable)
  -            {
  -                sfc = (StatementsForClassIF) new StatementsForClassImpl(conMan.getConnectionDescriptor(), cds);
  -                statementTable.put(cds, sfc);
  -            }
  -        }
  -        return sfc;
  -    }
  -
  -    public void closeResources(Statement stmt, ResultSet rs)
  -    {
  -        if (log.isDebugEnabled()) log.debug("closeResources was called");
  -        try
  -        {
  -            platform.beforeStatementClose(stmt, rs);
  -            //close statement on wrapped statement class, or real statement
  -            if (stmt != null)
  -            {
  -                //log.info("## close: "+stmt);
  -                stmt.close();
  -
  -                /*
  -                *********************************************
  -                special stuff for OJB within JBoss
  -                ********************************************
  -                */
  -                if (m_eagerRelease)
  -                {
  -                    conMan.releaseConnection();
  -                }
  -
  -            }
  -            platform.afterStatementClose(stmt, rs);
  -        }
  -        catch (PlatformException e)
  -        {
  -            log.error("Platform dependent operation failed", e);
  -        }
  -        catch (SQLException ignored)
  -        {
  -            if (log.isDebugEnabled()) log.debug("Statement closing failed", ignored);
  -        }
  -    }
  -
  -    /**
  -     * binds the Identities Primary key values to the statement
  -     */
  -    public void bindDelete(PreparedStatement stmt, Identity oid, ClassDescriptor cld) throws java.sql.SQLException
  -    {
  -        if (cld == null)
  -        {
  -            cld = broker.getClassDescriptor(oid.getObjectsClass());
  -        }
  -        for (int i = 0; i < oid.getPrimaryKeyValues().length; i++)
  -        {
  -            platform.setObjectForStatement(stmt, i + 1, oid.getPrimaryKeyValues()[i], SqlHelper.getSqlTypePk(cld, i));
  -        }
  -    }
  -
  -    /**
  -     * binds the objects primary key and locking values to the statement, BRJ
  -     */
  -    public void bindDelete(PreparedStatement stmt, ClassDescriptor cld, Object obj) throws java.sql.SQLException
  -    {
  -        int index = 1;
  -        Object[] values, currentLockingValues;
  -
  -        currentLockingValues = cld.getCurrentLockingValues(obj);
  -
  -        // parameters for WHERE-clause pk
  -        values = broker.serviceBrokerHelper().getKeyValues(cld, obj);
  -        for (int i = 0; i < values.length; i++)
  -        {
  -            platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypePk(cld, i));
  -            index++;
  -        }
  -
  -        // parameters for WHERE-clause locking
  -        values = currentLockingValues;
  -        for (int i = 0; i < values.length; i++)
  -        {
  -            platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypeLocking(cld, i));
  -            index++;
  -        }
  -    }
  -
  -    /**
  -     * bind a value
  -     * @param stmt the PreparedStatement
  -     * @param index the position of the parameter to bind
  -     * @param attributeName the query attribute to bind
  -     * @param value the value to bind
  -     * @param cld the ClassDescriptor
  -     * @return next index for PreparedStatement
  -     */
  -    private int bindStatementValue(
  -            PreparedStatement stmt,
  -            int index,
  -            Object value,
  -            ClassDescriptor cld,
  -            FieldDescriptor fld)
  -            throws SQLException
  -    {
  -        // if value is a subQuery bind it
  -        if (value instanceof Query)
  -        {
  -            Query subQuery = (Query) value;
  -            if (subQuery.getCriteria() != null && !subQuery.getCriteria().isEmpty())
  -            {
  -                return bindStatement(
  -                        stmt,
  -                        subQuery.getCriteria(),
  -                        cld.getRepository().getDescriptorFor(subQuery.getSearchClass()),
  -                        index);
  -            }
  -            return index;
  -        }
  -
  -        // if query has criteria, bind them
  -        if (fld != null)
  -        {
  -            // BRJ: use field conversions and platform
  -            if (value != null)
  -            {
  -                platform.setObjectForStatement(
  -                        stmt,
  -                        index,
  -                        fld.getFieldConversion().javaToSql(value),
  -                        fld.getColumnJdbcType());
  -            }
  -            else
  -            {
  -                platform.setNullForStatement(stmt, index, fld.getColumnJdbcType());
  -            }
  -        }
  -        else
  -        {
  -            // BRJ: No FieldDescriptor found
  -            if (value != null)
  -            {
  -                stmt.setObject(index, value);
  -            }
  -            else
  -            {
  -                stmt.setNull(index, Types.NULL);
  -            }
  -        }
  -
  -        return ++index; // increment before return
  -    }
  -
  -    /**
  -     * 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
  -    {
  -        FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
  -        return bindStatementValue(stmt, index, crit.getValue(), cld, fld);
  -    }
  -
  -    /**
  -     * 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) throws SQLException
  -    {
  -        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)
  -            throws SQLException
  -    {
  -        return index;
  -    }
  -
  -    /**
  -     * bind ColumnCriteria
  -     * @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, ColumnCriteria crit)
  -            throws SQLException
  -    {
  -        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) throws SQLException
  -    {
  -        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
  -    {
  -        FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
  -        index = bindStatementValue(stmt, index, crit.getValue(), cld, fld);
  -        return bindStatementValue(stmt, index, crit.getValue2(), cld, fld);
  -    }
  -
  -    /**
  -     * bind InCriteria
  -     * @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, InCriteria crit, ClassDescriptor cld) throws SQLException
  -    {
  -        FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
  -        if (crit.getValue() instanceof Collection)
  -        {
  -            Collection values = (Collection) crit.getValue();
  -            Iterator iter = values.iterator();
  -
  -            while (iter.hasNext())
  -            {
  -                index = bindStatementValue(stmt, index, iter.next(), cld, fld);
  -            }
  -        }
  -        else
  -        {
  -            index = bindStatementValue(stmt, index, crit.getValue(), cld, fld);
  -        }
  -        return index;
  -    }
  -
  -    /**
  -     * bind ExistsCriteria
  -     * @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,
  -            ExistsCriteria crit,
  -            ClassDescriptor cld)
  -            throws SQLException
  -    {
  -        Query subQuery = (Query) crit.getValue();
  -
  -        // if query has criteria, bind them
  -        if (subQuery.getCriteria() != null && !subQuery.getCriteria().isEmpty())
  -        {
  -            return bindStatement(
  -                    stmt,
  -                    subQuery.getCriteria(),
  -                    cld.getRepository().getDescriptorFor(subQuery.getSearchClass()),
  -                    index);
  -
  -            // otherwise, just ignore it
  -        }
  -        else
  -        {
  -            return index;
  -        }
  -    }
  -
  -    /**
  -     * bind a Query based Select Statement
  -     */
  -    public int bindStatement(PreparedStatement stmt, Criteria crit, ClassDescriptor cld, int param)
  -            throws SQLException
  -    {
  -        if (crit != null)
  -        {
  -            Enumeration e = crit.getElements();
  -
  -            while (e.hasMoreElements())
  -            {
  -                Object o = e.nextElement();
  -                if (o instanceof Criteria)
  -                {
  -                    Criteria pc = (Criteria) o;
  -                    param = bindStatement(stmt, pc, cld, param);
  -                }
  -                else
  -                {
  -                    SelectionCriteria c = (SelectionCriteria) o;
  -                    
  -                    // BRJ : bind once for the criterion's main class 
  -                    param = bindSelectionCriteria(stmt, param, c, cld);
  -
  -                    // BRJ : and once for each extent 
  -                    for (int i = 0; i < c.getNumberOfExtentsToBind(); i++)
  -                    {
  -                        param = bindSelectionCriteria(stmt, param, c, cld);
  -                    }
  -                }
  -            }
  -        }
  -        return param;
  -    }
  -
  -    /**
  -     * 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 bindSelectionCriteria(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld)
  -            throws SQLException
  -    {
  -        if (crit instanceof NullCriteria)
  -            index = bindStatement(stmt, index, (NullCriteria) crit);
  -        else if (crit instanceof BetweenCriteria)
  -            index = bindStatement(stmt, index, (BetweenCriteria) crit, cld);
  -        else if (crit instanceof InCriteria)
  -            index = bindStatement(stmt, index, (InCriteria) crit, cld);
  -        else if (crit instanceof SqlCriteria)
  -            index = bindStatement(stmt, index, (SqlCriteria) crit);
  -        else if (crit instanceof FieldCriteria)
  -            index = bindStatement(stmt, index, (FieldCriteria) crit);
  -        else if (crit instanceof ColumnCriteria)
  -            index = bindStatement(stmt, index, (ColumnCriteria) crit);
  -        else if (crit instanceof ExistsCriteria)
  -            index = bindStatement(stmt, index, (ExistsCriteria) crit, cld);
  -        else
  -            index = bindStatement(stmt, index, crit, cld);
  -
  -        return index;
  -    }
  -
  -
  -    /**
  -     * binds the values of the object obj to the statements parameters
  -     */
  -    public void bindInsert(PreparedStatement stmt, ClassDescriptor cld, Object obj)
  -            throws java.sql.SQLException
  -    {
  -        Object[] values;
  -        cld.updateLockingValues(obj); // BRJ : provide useful defaults for locking fields
  -
  -        values = getAllValues(cld, obj);
  -        for (int i = 0; i < values.length; i++)
  -        {
  -            Object val = values[i];
  -            if (val != null)
  -            {
  -                platform.setObjectForStatement(stmt, i + 1, val, SqlHelper.getSqlTypeAll(cld, i));
  -            }
  -            else
  -            {
  -                platform.setNullForStatement(stmt, i + 1, SqlHelper.getSqlTypeAll(cld, i));
  -            }
  -
  -        }
  -    }
  -
  -    /**
  -     * binds the Identities Primary key values to the statement
  -     */
  -    public void bindSelect(PreparedStatement stmt, Identity oid, ClassDescriptor cld) throws SQLException
  -    {
  -        if (cld == null)
  -        {
  -            cld = broker.getClassDescriptor(oid.getObjectsClass());
  -        }
  -        int i = 0;
  -        try
  -        {
  -            Object[] values = oid.getPrimaryKeyValues();
  -            for (i = 0; i < values.length; i++)
  -            {
  -                Object val = values[i];
  -                if (val != null)
  -                {
  -                    platform.setObjectForStatement(stmt, i + 1, val, SqlHelper.getSqlTypePk(cld, i));
  -                }
  -                else
  -                {
  -                    platform.setNullForStatement(stmt, i + 1, SqlHelper.getSqlTypePk(cld, i));
  -                }
  -            }
  -        }
  -        catch (SQLException e)
  -        {
  -            log.error(
  -                    "bindSelect failed for: "
  -                    + oid.toString()
  -                    + ", PK: "
  -                    + i
  -                    + ", value: "
  -                    + oid.getPrimaryKeyValues()[i]);
  -            throw e;
  -        }
  -    }
  -
  -    /**
  -     * binds the values of the object obj to the statements parameters
  -     */
  -    public void bindUpdate(PreparedStatement stmt, ClassDescriptor cld, Object obj)
  -            throws java.sql.SQLException
  -    {
  -        int index = 1;
  -        Object[] values, currentLockingValues;
  -
  -        currentLockingValues = cld.getCurrentLockingValues(obj);
  -        cld.updateLockingValues(obj); // BRJ
  -        values = getNonKeyValues(broker, cld, obj);
  -
  -        // parameters for SET-clause
  -        for (int i = 0; i < values.length; i++)
  -        {
  -            Object val = values[i];
  -            if (val != null)
  -                platform.setObjectForStatement(stmt, index, val, SqlHelper.getSqlTypeNonPk(cld, i));
  -            else
  -                platform.setNullForStatement(stmt, index, SqlHelper.getSqlTypeNonPk(cld, i));
  -            index++;
  -        }
  -        // parameters for WHERE-clause pk
  -        values = broker.serviceBrokerHelper().getKeyValues(cld, obj);
  -        for (int i = 0; i < values.length; i++)
  -        {
  -            Object val = values[i];
  -            if (val != null)
  -                stmt.setObject(index, values[i]);
  -            else
  -                stmt.setNull(index, SqlHelper.getSqlTypePk(cld, i));
  -
  -            index++;
  -        }
  -        // parameters for WHERE-clause locking
  -        values = currentLockingValues;
  -        for (int i = 0; i < values.length; i++)
  -        {
  -            Object val = values[i];
  -            if (val != null)
  -                stmt.setObject(index, values[i]);
  -            else
  -                stmt.setNull(index, SqlHelper.getSqlTypeNonPk(cld, i));
  -
  -            index++;
  -        }
  -    }
  -
  -    /**
  -     * binds the given array of values (if not null) starting from the given
  -     * parameter index
  -     * @return the next parameter index
  -     */
  -    public int bindValues(PreparedStatement stmt, Object[] values, int index) 
  -            throws SQLException
  -    {
  -        if (values != null)
  -        {
  -            for (int i = 0; i < values.length; i++)
  -            {
  -                platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypeByValue(values[i]));
  -                index++;
  -            }
  -        }
  -        return index;
  -    }
  -
  -    /**
  -     * return a prepared DELETE Statement fitting for the given ClassDescriptor
  -     */
  -    public PreparedStatement getDeleteStatement(ClassDescriptor cld)
  -            throws PersistenceBrokerSQLException, PersistenceBrokerException
  -    {
  -        try
  -        {
  -            return getStatementsForClass(cld).getDeleteStmt(broker.serviceConnectionManager().getConnection());
  -        }
  -        catch (SQLException e)
  -        {
  -            throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
  -        }
  -        catch (LookupException e)
  -        {
  -            throw new PersistenceBrokerException(
  -                    "Used ConnectionManager instance could not obtain a connection", e);
  -        }
  -    }
  -
  -    /**
  -     * return a generic Statement for the given ClassDescriptor.
  -     * Never use this method for UPDATE/INSERT/DELETE if you want to use the batch mode.
  -     */
  -    public Statement getGenericStatement(ClassDescriptor cds, boolean scrollable) throws PersistenceBrokerException
  -    {
  -        try
  -        {
  -            return getStatementsForClass(cds).getGenericStmt(conMan.getConnection(), scrollable);
  -        }
  -        catch (LookupException e)
  -        {
  -            throw new PersistenceBrokerException(
  -                    "Used ConnectionManager instance could not obtain a connection", e);
  -        }
  -    }
  -
  -    /**
  -     * return a prepared Insert Statement fitting for the given ClassDescriptor
  -     */
  -    public PreparedStatement getInsertStatement(ClassDescriptor cds)
  -            throws PersistenceBrokerSQLException, PersistenceBrokerException
  -    {
  -        try
  -        {
  -            return getStatementsForClass(cds).getInsertStmt(conMan.getConnection());
  -        }
  -        catch (SQLException e)
  -        {
  -            throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
  -        }
  -        catch (LookupException e)
  -        {
  -            throw new PersistenceBrokerException(
  -                    "Used ConnectionManager instance could not obtain a connection", e);
  -        }
  -    }
  -
  -    /**
  -     * return a generic Statement for the given ClassDescriptor
  -     */
  -    public PreparedStatement getPreparedStatement(ClassDescriptor cds, String sql, boolean scrollable)
  -            throws PersistenceBrokerException
  -    {
  -        try
  -        {
  -            return getStatementsForClass(cds).getPreparedStmt(conMan.getConnection(), sql, scrollable);
  -        }
  -        catch (LookupException e)
  -        {
  -            throw new PersistenceBrokerException(
  -                    "Used ConnectionManager instance could not obtain a connection", e);
  -        }
  -    }
  -
  -    /**
  -     * return a prepared Select Statement for the given ClassDescriptor
  -     */
  -    public PreparedStatement getSelectByPKStatement(ClassDescriptor cds)
  -            throws PersistenceBrokerSQLException, PersistenceBrokerException
  -    {
  -        try
  -        {
  -            return getStatementsForClass(cds).getSelectByPKStmt(conMan.getConnection());
  -        }
  -        catch (SQLException e)
  -        {
  -            throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
  -        }
  -        catch (LookupException e)
  -        {
  -            throw new PersistenceBrokerException(
  -                    "Used ConnectionManager instance could not obtain a connection", e);
  -        }
  -    }
  -
  -    /**
  -     * return a prepared Update Statement fitting to the given ClassDescriptor
  -     */
  -    public PreparedStatement getUpdateStatement(ClassDescriptor cds)
  -            throws PersistenceBrokerSQLException, PersistenceBrokerException
  -    {
  -        try
  -        {
  -            return getStatementsForClass(cds).getUpdateStmt(conMan.getConnection());
  -        }
  -        catch (SQLException e)
  -        {
  -            throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
  -        }
  -        catch (LookupException e)
  -        {
  -            throw new PersistenceBrokerException(
  -                    "Used ConnectionManager instance could not obtain a connection", e);
  -        }
  -    }
  -
  -    /**
  -     * returns an array containing values for all the Objects attribute
  -     * @throws MetadataException if tehre is an erros accessing obj field values
  -     */
  -    protected Object[] getAllValues(ClassDescriptor cld, Object obj) throws PersistenceBrokerException
  -    {
  -        FieldDescriptor[] allFields = cld.getFieldDescriptions();
  -        Object[] result = new Object[allFields.length];
  -
  -        for (int i = 0; i < allFields.length; i++)
  -        {
  -            FieldDescriptor fmd = allFields[i];
  -            PersistentField f = fmd.getPersistentField();
  -            Object cv = f.get(obj);
  -
  -            // handle autoincrement attributes if not filled
  -            if (fmd.isAutoIncrement())
  -            {
  -                cv = broker.serviceBrokerHelper().getAutoIncrementValue(fmd, obj, cv);
  -            }
  -
  -            // apply type and value mapping
  -            cv = fmd.getFieldConversion().javaToSql(cv);
  -            result[i] = cv;
  -        }
  -        return result;
  -    }
  -
  -    /**
  -     * returns an Array with an Objects NON-PK VALUES
  -     * @throws MetadataException if there is an erros accessing o field values
  -     */
  -    protected Object[] getNonKeyValues(PersistenceBroker broker, ClassDescriptor cld, Object o) throws PersistenceBrokerException
  -    {
  -        FieldDescriptor[] nonPkFields = cld.getNonPkFields();
  -        Object[] result = new Object[nonPkFields.length];
  -
  -        for (int i = 0; i < result.length; i++)
  -        {
  -            FieldDescriptor fmd = nonPkFields[i];
  -            PersistentField f = fmd.getPersistentField();
  -            Object cv = f.get(o);
  -
  -            // handle autoincrement attributes if not filled
  -            if (fmd.isAutoIncrement())
  -            {
  -                cv = broker.serviceBrokerHelper().getAutoIncrementValue(fmd, o, cv);
  -            }
  -
  -            // apply type and value conversion
  -            cv = fmd.getFieldConversion().javaToSql(cv);
  -            result[i] = cv;
  -        }
  -        return result;
  -    }
  -
  -    /**
  -     * MBAIRD: I would prefer to remove statement caching completely, but instead we
  -     * deal with edge cases.
  -     */
  -    private void closeIfNotCached(Statement stmt)
  -    {
  -        boolean doClose = true;
  -        synchronized (statementTable)
  -        {
  -            for (Iterator it = statementTable.values().iterator(); it.hasNext();)
  -            {
  -                StatementsForClassIF sfc = (StatementsForClassIF) it.next();
  -                if (sfc != null)
  -                {
  -                    if (sfc.isCached(stmt))
  -                    {
  -                        doClose = false;
  -                        break;
  -                    }
  -                }
  -            }
  -        }
  -        if (doClose)
  -        {
  -            try
  -            {
  -                stmt.close();
  -            }
  -            catch (SQLException ignored)
  -            {
  -                LoggerFactory.getDefaultLogger().warn("closing statement had error: " + ignored.getMessage());
  -            }
  -        }
  -    }
  +	/** internal table of StatementForClass objects */
  +	private Map statementTable = new WeakHashMap();
  +	/** the associated broker */
  +	private final PersistenceBroker broker;
  +	private Platform platform;
  +	/**
  +	 * Used when OJB run in JBoss
  +	 * @todo Find a better solution to handle OJB within JBoss
  +	 * --> the JCA implementation should solve this problem
  +	 */
  +	private boolean m_eagerRelease;
  +	private ConnectionManagerIF conMan;
  +
  +	public StatementManager(final PersistenceBroker pBroker)
  +	{
  +		this.broker = pBroker;
  +		this.conMan = broker.serviceConnectionManager();
  +		m_eagerRelease = conMan.getConnectionDescriptor().getEagerRelease();
  +		platform = PlatformFactory.getPlatformFor(conMan.getConnectionDescriptor());
  +	}
  +
  +	/**
  +	 * return a StatementsForClass object for the given ClassDescriptor\
  +	 * Note; not important to synchronize completely as a threading issue in this code
  +	 * will only result in a little extra code being executed
  +	 */
  +	protected StatementsForClassIF getStatementsForClass(ClassDescriptor cds) throws PersistenceBrokerException
  +	{
  +		StatementsForClassIF sfc = (StatementsForClassIF) statementTable.get(cds);
  +		if (sfc == null)
  +		{
  +			synchronized (statementTable)
  +			{
  +				sfc = (StatementsForClassIF) new StatementsForClassImpl(conMan.getConnectionDescriptor(), cds);
  +				statementTable.put(cds, sfc);
  +			}
  +		}
  +		return sfc;
  +	}
  +
  +	public void closeResources(Statement stmt, ResultSet rs)
  +	{
  +		if (log.isDebugEnabled())
  +			log.debug("closeResources was called");
  +		try
  +		{
  +			platform.beforeStatementClose(stmt, rs);
  +			//close statement on wrapped statement class, or real statement
  +			if (stmt != null)
  +			{
  +				//log.info("## close: "+stmt);
  +				stmt.close();
  +
  +				/*
  +				*********************************************
  +				special stuff for OJB within JBoss
  +				********************************************
  +				*/
  +				if (m_eagerRelease)
  +				{
  +					conMan.releaseConnection();
  +				}
  +
  +			}
  +			platform.afterStatementClose(stmt, rs);
  +		}
  +		catch (PlatformException e)
  +		{
  +			log.error("Platform dependent operation failed", e);
  +		}
  +		catch (SQLException ignored)
  +		{
  +			if (log.isDebugEnabled())
  +				log.debug("Statement closing failed", ignored);
  +		}
  +	}
  +
  +	/**
  +	 * binds the Identities Primary key values to the statement
  +	 */
  +	public void bindDelete(PreparedStatement stmt, Identity oid, ClassDescriptor cld) throws java.sql.SQLException
  +	{
  +		Object[] values = null;
  +		int i = 0;
  +
  +		if (cld == null)
  +		{
  +			cld = broker.getClassDescriptor(oid.getObjectsClass());
  +		}
  +
  +		values = getKeyValues(broker, cld, oid);
  +
  +		try
  +		{
  +			for (i = 0; i < values.length; i++)
  +			{
  +				platform.setObjectForStatement(stmt, i + 1, values[i], SqlHelper.getSqlTypePk(cld, i));
  +			}
  +		}
  +		catch (SQLException e)
  +		{
  +			log.error("bindDelete failed for: " + oid.toString() + ", PK: " + i + ", value: " + values[i]);
  +			throw e;
  +		}
  +	}
  +
  +	/**
  +	 * binds the objects primary key and locking values to the statement, BRJ
  +	 */
  +	public void bindDelete(PreparedStatement stmt, ClassDescriptor cld, Object obj) throws java.sql.SQLException
  +	{
  +		int index = 1;
  +		Object[] values, currentLockingValues;
  +
  +		currentLockingValues = cld.getCurrentLockingValues(obj);
  +
  +		// parameters for WHERE-clause pk
  +		values = getKeyValues(broker, cld, obj);
  +		for (int i = 0; i < values.length; i++)
  +		{
  +			platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypePk(cld, i));
  +			index++;
  +		}
  +
  +		// parameters for WHERE-clause locking
  +		values = currentLockingValues;
  +		for (int i = 0; i < values.length; i++)
  +		{
  +			platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypeLocking(cld, i));
  +			index++;
  +		}
  +	}
  +
  +	/**
  +	 * bind a value
  +	 * @param stmt the PreparedStatement
  +	 * @param index the position of the parameter to bind
  +	 * @param attributeName the query attribute to bind
  +	 * @param value the value to bind
  +	 * @param cld the ClassDescriptor
  +	 * @return next index for PreparedStatement
  +	 */
  +	private int bindStatementValue(PreparedStatement stmt, int index, Object value, ClassDescriptor cld, FieldDescriptor fld)
  +		throws SQLException
  +	{
  +		// if value is a subQuery bind it
  +		if (value instanceof Query)
  +		{
  +			Query subQuery = (Query) value;
  +			if (subQuery.getCriteria() != null && !subQuery.getCriteria().isEmpty())
  +			{
  +				return bindStatement(stmt, subQuery.getCriteria(), cld.getRepository().getDescriptorFor(subQuery.getSearchClass()), index);
  +			}
  +			return index;
  +		}
  +
  +		// if query has criteria, bind them
  +		if (fld != null)
  +		{
  +			// BRJ: use field conversions and platform
  +			if (value != null)
  +			{
  +				platform.setObjectForStatement(stmt, index, fld.getFieldConversion().javaToSql(value), fld.getColumnJdbcType());
  +			}
  +			else
  +			{
  +				platform.setNullForStatement(stmt, index, fld.getColumnJdbcType());
  +			}
  +		}
  +		else
  +		{
  +			// BRJ: No FieldDescriptor found
  +			if (value != null)
  +			{
  +				stmt.setObject(index, value);
  +			}
  +			else
  +			{
  +				stmt.setNull(index, Types.NULL);
  +			}
  +		}
  +
  +		return ++index; // increment before return
  +	}
  +
  +	/**
  +	 * 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
  +	{
  +		FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
  +		return bindStatementValue(stmt, index, crit.getValue(), cld, fld);
  +	}
  +
  +	/**
  +	 * 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) throws SQLException
  +	{
  +		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) throws SQLException
  +	{
  +		return index;
  +	}
  +
  +	/**
  +	 * bind ColumnCriteria
  +	 * @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, ColumnCriteria crit) throws SQLException
  +	{
  +		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) throws SQLException
  +	{
  +		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
  +	{
  +		FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
  +		index = bindStatementValue(stmt, index, crit.getValue(), cld, fld);
  +		return bindStatementValue(stmt, index, crit.getValue2(), cld, fld);
  +	}
  +
  +	/**
  +	 * bind InCriteria
  +	 * @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, InCriteria crit, ClassDescriptor cld) throws SQLException
  +	{
  +		FieldDescriptor fld = cld.getFieldDescriptorForPath(crit.getAttribute());
  +		if (crit.getValue() instanceof Collection)
  +		{
  +			Collection values = (Collection) crit.getValue();
  +			Iterator iter = values.iterator();
  +
  +			while (iter.hasNext())
  +			{
  +				index = bindStatementValue(stmt, index, iter.next(), cld, fld);
  +			}
  +		}
  +		else
  +		{
  +			index = bindStatementValue(stmt, index, crit.getValue(), cld, fld);
  +		}
  +		return index;
  +	}
  +
  +	/**
  +	 * bind ExistsCriteria
  +	 * @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, ExistsCriteria crit, ClassDescriptor cld) throws SQLException
  +	{
  +		Query subQuery = (Query) crit.getValue();
  +
  +		// if query has criteria, bind them
  +		if (subQuery.getCriteria() != null && !subQuery.getCriteria().isEmpty())
  +		{
  +			return bindStatement(stmt, subQuery.getCriteria(), cld.getRepository().getDescriptorFor(subQuery.getSearchClass()), index);
  +
  +			// otherwise, just ignore it
  +		}
  +		else
  +		{
  +			return index;
  +		}
  +	}
  +
  +	/**
  +	 * bind a Query based Select Statement
  +	 */
  +	public int bindStatement(PreparedStatement stmt, Criteria crit, ClassDescriptor cld, int param) throws SQLException
  +	{
  +		if (crit != null)
  +		{
  +			Enumeration e = crit.getElements();
  +
  +			while (e.hasMoreElements())
  +			{
  +				Object o = e.nextElement();
  +				if (o instanceof Criteria)
  +				{
  +					Criteria pc = (Criteria) o;
  +					param = bindStatement(stmt, pc, cld, param);
  +				}
  +				else
  +				{
  +					SelectionCriteria c = (SelectionCriteria) o;
  +
  +					// BRJ : bind once for the criterion's main class 
  +					param = bindSelectionCriteria(stmt, param, c, cld);
  +
  +					// BRJ : and once for each extent 
  +					for (int i = 0; i < c.getNumberOfExtentsToBind(); i++)
  +					{
  +						param = bindSelectionCriteria(stmt, param, c, cld);
  +					}
  +				}
  +			}
  +		}
  +		return param;
  +	}
  +
  +	/**
  +	 * 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 bindSelectionCriteria(PreparedStatement stmt, int index, SelectionCriteria crit, ClassDescriptor cld) throws SQLException
  +	{
  +		if (crit instanceof NullCriteria)
  +			index = bindStatement(stmt, index, (NullCriteria) crit);
  +		else if (crit instanceof BetweenCriteria)
  +			index = bindStatement(stmt, index, (BetweenCriteria) crit, cld);
  +		else if (crit instanceof InCriteria)
  +			index = bindStatement(stmt, index, (InCriteria) crit, cld);
  +		else if (crit instanceof SqlCriteria)
  +			index = bindStatement(stmt, index, (SqlCriteria) crit);
  +		else if (crit instanceof FieldCriteria)
  +			index = bindStatement(stmt, index, (FieldCriteria) crit);
  +		else if (crit instanceof ColumnCriteria)
  +			index = bindStatement(stmt, index, (ColumnCriteria) crit);
  +		else if (crit instanceof ExistsCriteria)
  +			index = bindStatement(stmt, index, (ExistsCriteria) crit, cld);
  +		else
  +			index = bindStatement(stmt, index, crit, cld);
  +
  +		return index;
  +	}
  +
  +	/**
  +	 * binds the values of the object obj to the statements parameters
  +	 */
  +	public void bindInsert(PreparedStatement stmt, ClassDescriptor cld, Object obj) throws java.sql.SQLException
  +	{
  +		Object[] values;
  +		cld.updateLockingValues(obj); // BRJ : provide useful defaults for locking fields
  +
  +		values = getAllValues(cld, obj);
  +		for (int i = 0; i < values.length; i++)
  +		{
  +			Object val = values[i];
  +			if (val != null)
  +			{
  +				platform.setObjectForStatement(stmt, i + 1, val, SqlHelper.getSqlTypeAll(cld, i));
  +			}
  +			else
  +			{
  +				platform.setNullForStatement(stmt, i + 1, SqlHelper.getSqlTypeAll(cld, i));
  +			}
  +
  +		}
  +	}
  +
  +	/**
  +	 * binds the Identities Primary key values to the statement
  +	 */
  +	public void bindSelect(PreparedStatement stmt, Identity oid, ClassDescriptor cld) throws SQLException
  +	{
  +		Object[] values = null;
  +		int i = 0;
  +
  +		if (cld == null)
  +		{
  +			cld = broker.getClassDescriptor(oid.getObjectsClass());
  +		}
  +		try
  +		{
  +			values = getKeyValues(broker, cld, oid);
  +			for (i = 0; i < values.length; i++)
  +			{
  +				Object val = values[i];
  +				if (val != null)
  +				{
  +					platform.setObjectForStatement(stmt, i + 1, val, SqlHelper.getSqlTypePk(cld, i));
  +				}
  +				else
  +				{
  +					platform.setNullForStatement(stmt, i + 1, SqlHelper.getSqlTypePk(cld, i));
  +				}
  +			}
  +		}
  +		catch (SQLException e)
  +		{
  +			log.error("bindSelect failed for: " + oid.toString() + ", PK: " + i + ", value: " + values[i]);
  +			throw e;
  +		}
  +	}
  +
  +	/**
  +	 * binds the values of the object obj to the statements parameters
  +	 */
  +	public void bindUpdate(PreparedStatement stmt, ClassDescriptor cld, Object obj) throws java.sql.SQLException
  +	{
  +		int index = 1;
  +		Object[] values, currentLockingValues;
  +
  +		currentLockingValues = cld.getCurrentLockingValues(obj);
  +		cld.updateLockingValues(obj); // BRJ
  +		values = getNonKeyValues(broker, cld, obj);
  +
  +		// parameters for SET-clause
  +		for (int i = 0; i < values.length; i++)
  +		{
  +			Object val = values[i];
  +			if (val != null)
  +				platform.setObjectForStatement(stmt, index, val, SqlHelper.getSqlTypeNonPk(cld, i));
  +			else
  +				platform.setNullForStatement(stmt, index, SqlHelper.getSqlTypeNonPk(cld, i));
  +			index++;
  +		}
  +		// parameters for WHERE-clause pk
  +		values = getKeyValues(broker, cld, obj);
  +		for (int i = 0; i < values.length; i++)
  +		{
  +			Object val = values[i];
  +			if (val != null)
  +				stmt.setObject(index, values[i]);
  +			else
  +				stmt.setNull(index, SqlHelper.getSqlTypePk(cld, i));
  +
  +			index++;
  +		}
  +		// parameters for WHERE-clause locking
  +		values = currentLockingValues;
  +		for (int i = 0; i < values.length; i++)
  +		{
  +			Object val = values[i];
  +			if (val != null)
  +				stmt.setObject(index, values[i]);
  +			else
  +				stmt.setNull(index, SqlHelper.getSqlTypeNonPk(cld, i));
  +
  +			index++;
  +		}
  +	}
  +
  +	/**
  +	 * binds the given array of values (if not null) starting from the given
  +	 * parameter index
  +	 * @return the next parameter index
  +	 */
  +	public int bindValues(PreparedStatement stmt, Object[] values, int index) throws SQLException
  +	{
  +		if (values != null)
  +		{
  +			for (int i = 0; i < values.length; i++)
  +			{
  +				platform.setObjectForStatement(stmt, index, values[i], SqlHelper.getSqlTypeByValue(values[i]));
  +				index++;
  +			}
  +		}
  +		return index;
  +	}
  +
  +	/**
  +	 * return a prepared DELETE Statement fitting for the given ClassDescriptor
  +	 */
  +	public PreparedStatement getDeleteStatement(ClassDescriptor cld) throws PersistenceBrokerSQLException, PersistenceBrokerException
  +	{
  +		try
  +		{
  +			return getStatementsForClass(cld).getDeleteStmt(broker.serviceConnectionManager().getConnection());
  +		}
  +		catch (SQLException e)
  +		{
  +			throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
  +		}
  +		catch (LookupException e)
  +		{
  +			throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
  +		}
  +	}
  +
  +	/**
  +	 * return a generic Statement for the given ClassDescriptor.
  +	 * Never use this method for UPDATE/INSERT/DELETE if you want to use the batch mode.
  +	 */
  +	public Statement getGenericStatement(ClassDescriptor cds, boolean scrollable) throws PersistenceBrokerException
  +	{
  +		try
  +		{
  +			return getStatementsForClass(cds).getGenericStmt(conMan.getConnection(), scrollable);
  +		}
  +		catch (LookupException e)
  +		{
  +			throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
  +		}
  +	}
  +
  +	/**
  +	 * return a prepared Insert Statement fitting for the given ClassDescriptor
  +	 */
  +	public PreparedStatement getInsertStatement(ClassDescriptor cds) throws PersistenceBrokerSQLException, PersistenceBrokerException
  +	{
  +		try
  +		{
  +			return getStatementsForClass(cds).getInsertStmt(conMan.getConnection());
  +		}
  +		catch (SQLException e)
  +		{
  +			throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
  +		}
  +		catch (LookupException e)
  +		{
  +			throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
  +		}
  +	}
  +
  +	/**
  +	 * return a generic Statement for the given ClassDescriptor
  +	 */
  +	public PreparedStatement getPreparedStatement(ClassDescriptor cds, String sql, boolean scrollable) throws PersistenceBrokerException
  +	{
  +		try
  +		{
  +			return getStatementsForClass(cds).getPreparedStmt(conMan.getConnection(), sql, scrollable);
  +		}
  +		catch (LookupException e)
  +		{
  +			throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
  +		}
  +	}
  +
  +	/**
  +	 * return a prepared Select Statement for the given ClassDescriptor
  +	 */
  +	public PreparedStatement getSelectByPKStatement(ClassDescriptor cds) throws PersistenceBrokerSQLException, PersistenceBrokerException
  +	{
  +		try
  +		{
  +			return getStatementsForClass(cds).getSelectByPKStmt(conMan.getConnection());
  +		}
  +		catch (SQLException e)
  +		{
  +			throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
  +		}
  +		catch (LookupException e)
  +		{
  +			throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
  +		}
  +	}
  +
  +	/**
  +	 * return a prepared Update Statement fitting to the given ClassDescriptor
  +	 */
  +	public PreparedStatement getUpdateStatement(ClassDescriptor cds) throws PersistenceBrokerSQLException, PersistenceBrokerException
  +	{
  +		try
  +		{
  +			return getStatementsForClass(cds).getUpdateStmt(conMan.getConnection());
  +		}
  +		catch (SQLException e)
  +		{
  +			throw new PersistenceBrokerSQLException("Could not build statement ask for", e);
  +		}
  +		catch (LookupException e)
  +		{
  +			throw new PersistenceBrokerException("Used ConnectionManager instance could not obtain a connection", e);
  +		}
  +	}
  +
  +	/**
  +	 * returns an array containing values for all the Objects attribute
  +	 * @throws MetadataException if tehre is an erros accessing obj field values
  +	 */
  +	protected Object[] getAllValues(ClassDescriptor cld, Object obj) throws PersistenceBrokerException
  +	{
  +		return broker.serviceBrokerHelper().getAllValues(cld, obj);
  +	}
  +
  +	/**
  +	 * returns an Array with an Objects PK VALUES
  +	 * @throws MetadataException if there is an erros accessing o field values
  +	 */
  +	protected Object[] getKeyValues(PersistenceBroker broker, ClassDescriptor cld, Object obj) throws PersistenceBrokerException
  +	{
  +		return broker.serviceBrokerHelper().getKeyValues(cld, obj);
  +	}
  +
  +	/**
  +	 * returns an Array with an Identities PK VALUES
  +	 * @throws MetadataException if there is an erros accessing o field values
  +	 */
  +	protected Object[] getKeyValues(PersistenceBroker broker, ClassDescriptor cld, Identity oid) throws PersistenceBrokerException
  +	{
  +        return oid.getPrimaryKeyValues();
  +	}
  +
  +	/**
  +	 * returns an Array with an Objects NON-PK VALUES
  +	 * @throws MetadataException if there is an erros accessing o field values
  +	 */
  +	protected Object[] getNonKeyValues(PersistenceBroker broker, ClassDescriptor cld, Object obj) throws PersistenceBrokerException
  +	{
  +		return broker.serviceBrokerHelper().getNonKeyValues(cld, obj);
  +	}
  +
  +	/**
  +	 * MBAIRD: I would prefer to remove statement caching completely, but instead we
  +	 * deal with edge cases.
  +	 */
  +	private void closeIfNotCached(Statement stmt)
  +	{
  +		boolean doClose = true;
  +		synchronized (statementTable)
  +		{
  +			for (Iterator it = statementTable.values().iterator(); it.hasNext();)
  +			{
  +				StatementsForClassIF sfc = (StatementsForClassIF) it.next();
  +				if (sfc != null)
  +				{
  +					if (sfc.isCached(stmt))
  +					{
  +						doClose = false;
  +						break;
  +					}
  +				}
  +			}
  +		}
  +		if (doClose)
  +		{
  +			try
  +			{
  +				stmt.close();
  +			}
  +			catch (SQLException ignored)
  +			{
  +				LoggerFactory.getDefaultLogger().warn("closing statement had error: " + ignored.getMessage());
  +			}
  +		}
  +	}
   }