You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by Patrick Linskey <pl...@gmail.com> on 2008/01/25 20:50:10 UTC

Re: svn commit: r614763 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ openjpa-kernel/src/main/ja

Hi,

Can you describe in more detail why you needed to make changes tho
Broker, Bootstrap, StateManagerImpl, and PersistenceProviderImpl?

-Patrick

On Jan 23, 2008 5:33 PM,  <fa...@apache.org> wrote:
> Author: fancy
> Date: Wed Jan 23 17:33:48 2008
> New Revision: 614763
>
> URL: http://svn.apache.org/viewvc?rev=614763&view=rev
> Log:
> OPENJPA-477 Making StoreManager more flexible and extensible
>
> Modified:
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/AbstractUpdateManager.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedStatementManagerImpl.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java
>     openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
>     openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Bootstrap.java
>     openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
>     openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
>     openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/AbstractUpdateManager.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/AbstractUpdateManager.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/AbstractUpdateManager.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/AbstractUpdateManager.java Wed Jan 23 17:33:48 2008
> @@ -181,7 +181,7 @@
>      /**
>       * Recursive method to insert the given instance, base class first.
>       */
> -    private void insert(OpenJPAStateManager sm, ClassMapping mapping,
> +    protected void insert(OpenJPAStateManager sm, ClassMapping mapping,
>          RowManager rowMgr, JDBCStore store, Collection customs)
>          throws SQLException {
>          Boolean custom = mapping.isCustomInsert(sm, store);
> @@ -228,7 +228,7 @@
>      /**
>       * Recursive method to delete the given instance, base class last.
>       */
> -    private void delete(OpenJPAStateManager sm, ClassMapping mapping,
> +    protected void delete(OpenJPAStateManager sm, ClassMapping mapping,
>          RowManager rowMgr, JDBCStore store, Collection customs)
>          throws SQLException {
>          Boolean custom = mapping.isCustomDelete(sm, store);
> @@ -271,7 +271,7 @@
>      /**
>       * Recursive method to update the given instance.
>       */
> -    private void update(OpenJPAStateManager sm, BitSet dirty,
> +    protected void update(OpenJPAStateManager sm, BitSet dirty,
>          ClassMapping mapping, RowManager rowMgr, JDBCStore store,
>          Collection customs) throws SQLException {
>          Boolean custom = mapping.isCustomUpdate(sm, store);
> @@ -300,7 +300,7 @@
>      /**
>       * Update version and discriminator indicators.
>       */
> -    private void updateIndicators(OpenJPAStateManager sm, ClassMapping mapping,
> +    protected void updateIndicators(OpenJPAStateManager sm, ClassMapping mapping,
>          RowManager rowMgr, JDBCStore store, Collection customs,
>          boolean versionUpdateOnly) throws SQLException {
>          while (mapping.getJoinablePCSuperclassMapping() != null)
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java Wed Jan 23 17:33:48 2008
> @@ -140,7 +140,7 @@
>      /**
>       * Synchronize the mappings of the classes listed in the configuration.
>       */
> -    private void synchronizeMappings(ClassLoader loader) {
> +    protected void synchronizeMappings(ClassLoader loader) {
>          JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
>          String action = conf.getSynchronizeMappings();
>          if (StringUtils.isEmpty(action))
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java Wed Jan 23 17:33:48 2008
> @@ -272,7 +272,7 @@
>      /**
>       * Initialize a newly-loaded instance.
>       */
> -    private boolean initializeState(OpenJPAStateManager sm, PCState state,
> +    protected boolean initializeState(OpenJPAStateManager sm, PCState state,
>          JDBCFetchConfiguration fetch, ConnectionInfo info)
>          throws ClassNotFoundException, SQLException {
>          Object oid = sm.getObjectId();
> @@ -294,7 +294,7 @@
>                      Select.SUBS_EXACT);
>                  if (res == null && !selectPrimaryKey(sm, mapping, fetch))
>                      return false;
> -                if (res != null && !res.next())
> +                if (isEmptyResult(res))
>                      return false;
>              } else {
>                  ClassMapping[] mappings = mapping.
> @@ -311,16 +311,14 @@
>                  } else
>                      res = getInitializeStateUnionResult(sm, mapping, mappings,
>                          fetch);
> -                if (res != null && !res.next())
> +                if (isEmptyResult(res))
>                      return false;
>              }
>
>              // figure out what type of object this is; the state manager
>              // only guarantees to provide a base class
>              Class type;
> -            if (res == null)
> -                type = mapping.getDescribedType();
> -            else {
> +            if ((type = getType(res, mapping)) == null) {
>                  if (res.getBaseMapping() != null)
>                      mapping = res.getBaseMapping();
>                  res.startDataRequest(mapping.getDiscriminator());
> @@ -342,7 +340,7 @@
>                  // re-get the mapping in case the instance was a subclass
>                  mapping = (ClassMapping) sm.getMetaData();
>                  load(mapping, sm, fetch, res);
> -                mapping.getVersion().afterLoad(sm, this);
> +                getVersion(mapping, sm, res);
>              }
>              return true;
>          } finally {
> @@ -350,6 +348,35 @@
>                  res.close();
>          }
>      }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of getting version from the result set.
> +     */
> +    protected void getVersion(ClassMapping mapping, OpenJPAStateManager sm,
> +        Result res) throws SQLException {
> +        mapping.getVersion().afterLoad(sm, this);
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of checking whether the result set is empty or not.
> +     */
> +    protected boolean isEmptyResult(Result res) throws SQLException {
> +        if (res != null && !res.next())
> +            return true;
> +        return false;
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of getting type from the result set.
> +     */
> +    protected Class getType(Result res, ClassMapping mapping){
> +        if (res == null)
> +            return mapping.getDescribedType();
> +        return null;
> +    }
>
>      /**
>       * Allow the mapping to custom load data. Return null if the mapping
> @@ -427,7 +454,7 @@
>          sel.wherePrimaryKey(sm.getObjectId(), base, this);
>          Result exists = sel.execute(this, fetch);
>          try {
> -            if (!exists.next())
> +            if (isEmptyResult(exists))
>                  return false;
>
>              // record locked?
> @@ -478,7 +505,7 @@
>                  sel.wherePrimaryKey(sm.getObjectId(), mapping, this);
>                  res = sel.execute(this, jfetch, lockLevel);
>                  try {
> -                    if (!res.next())
> +                       if (isEmptyResult(res))
>                          return false;
>                      load(mapping, sm, jfetch, res);
>                  } finally {
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java Wed Jan 23 17:33:48 2008
> @@ -499,11 +499,11 @@
>              for (int i = 0; i < sql.length; i++) {
>                  stmnt = null;
>                  try {
> -                    stmnt = sql[i].prepareStatement(conn);
> -                    count += stmnt.executeUpdate();
> +                    stmnt = prepareStatement(conn, sql[i]);
> +                    count += executeUpdate(conn, stmnt, sql[i], isUpdate);
>                  } catch (SQLException se) {
>                      throw SQLExceptions.getStore(se, sql[i].getSQL(),
> -                               _store.getDBDictionary());
> +                        _store.getDBDictionary());
>                  } finally {
>                      if (stmnt != null)
>                          try { stmnt.close(); } catch (SQLException se) {}
> @@ -649,4 +649,22 @@
>              sql[i] = ((Select) sels.get(i)).toSelect(false, fetch).getSQL(true);
>          return sql;
>      }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of executing update.
> +     */
> +    protected int executeUpdate(Connection conn, PreparedStatement stmnt,
> +        SQLBuffer sqlBuf, boolean isUpdate) throws SQLException {
> +        return stmnt.executeUpdate();
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of preparing statement.
> +     */
> +    protected PreparedStatement prepareStatement(Connection conn, SQLBuffer sql)
> +        throws SQLException {
> +        return sql.prepareStatement(conn);
> +    }
>  }
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java Wed Jan 23 17:33:48 2008
> @@ -132,18 +132,10 @@
>          PreparedStatement stmnt = null;
>          ResultSet rs = null;
>          try {
> -            stmnt = sql.prepareStatement(conn);
> -            if (timeout >= 0 && dict.supportsQueryTimeout) {
> -                if (timeout < 1000) {
> -                    timeout = 1000;
> -                    if (log.isWarnEnabled())
> -                        log.warn(_loc.get("millis-query-timeout"));
> -                }
> -                stmnt.setQueryTimeout(timeout / 1000);
> -            }
> -            rs = stmnt.executeQuery();
> -            if (!rs.next())
> -                throw new LockException(sm.getManagedInstance());
> +            stmnt = prepareStatement(conn, sql);
> +            setTimeout(stmnt, timeout);
> +            rs = executeQuery(conn, stmnt, sql);
> +            checkLock(rs, sm);
>          } catch (SQLException se) {
>              throw SQLExceptions.getStore(se, dict);
>          } finally {
> @@ -167,5 +159,55 @@
>              if (log.isInfoEnabled())
>                  log.info(_loc.get("start-trans-for-lock"));
>          }
> +    }
> +
> +    public JDBCStore getStore() {
> +        return _store;
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of preparing statement.
> +     */
> +    protected PreparedStatement prepareStatement(Connection conn, SQLBuffer sql)
> +        throws SQLException {
> +        return sql.prepareStatement(conn);
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of setting query timeout.
> +     */
> +    protected void setTimeout(PreparedStatement stmnt, int timeout)
> +        throws SQLException {
> +        DBDictionary dict = _store.getDBDictionary();
> +        if (timeout >= 0 && dict.supportsQueryTimeout) {
> +            if (timeout < 1000) {
> +                timeout = 1000;
> +                if (log.isWarnEnabled())
> +                    log.warn(_loc.get("millis-query-timeout"));
> +            }
> +            stmnt.setQueryTimeout(timeout / 1000);
> +        }
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of executing query.
> +     */
> +    protected ResultSet executeQuery(Connection conn, PreparedStatement stmnt,
> +        SQLBuffer sql) throws SQLException {
> +        return stmnt.executeQuery();
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of checking lock from the result set.
> +     */
> +    protected void checkLock(ResultSet rs, OpenJPAStateManager sm)
> +        throws SQLException {
> +        if (!rs.next())
> +            throw new LockException(sm.getManagedInstance());
> +        return;
>      }
>  }
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedStatementManagerImpl.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedStatementManagerImpl.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedStatementManagerImpl.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedStatementManagerImpl.java Wed Jan 23 17:33:48 2008
> @@ -35,7 +35,6 @@
>  import org.apache.openjpa.util.ApplicationIds;
>  import org.apache.openjpa.util.OpenJPAException;
>  import org.apache.openjpa.util.OptimisticException;
> -import org.apache.openjpa.meta.ClassMetaData;
>
>  /**
>   * Basic prepared statement manager implementation.
> @@ -89,12 +88,13 @@
>
>          // prepare statement
>          String sql = row.getSQL(_dict);
> -        PreparedStatement stmnt = _conn.prepareStatement(sql);
> -
> +        PreparedStatement stmnt = prepareStatement(sql);
> +
>          // setup parameters and execute statement
> -        row.flush(stmnt, _dict, _store);
> +        if (stmnt != null)
> +            row.flush(stmnt, _dict, _store);
>          try {
> -            int count = stmnt.executeUpdate();
> +            int count = executeUpdate(stmnt, sql, row);
>              if (count != 1) {
>                  Object failed = row.getFailedObject();
>                  if (failed != null)
> @@ -107,7 +107,8 @@
>          } catch (SQLException se) {
>              throw SQLExceptions.getStore(se, row.getFailedObject(), _dict);
>          } finally {
> -            try { stmnt.close(); } catch (SQLException se) {}
> +            if (stmnt != null)
> +               try { stmnt.close(); } catch (SQLException se) {}
>          }
>
>          // set auto assign values
> @@ -128,4 +129,22 @@
>
>      public void flush() {
>      }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of executing update.
> +     */
> +    protected int executeUpdate(PreparedStatement stmnt, String sql,
> +        RowImpl row) throws SQLException {
> +        return stmnt.executeUpdate();
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of preparing statement.
> +     */
> +    protected PreparedStatement prepareStatement(String sql)
> +        throws SQLException {
> +        return _conn.prepareStatement(sql);
> +    }
>  }
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java Wed Jan 23 17:33:48 2008
> @@ -23,6 +23,7 @@
>  import java.io.StringReader;
>  import java.sql.Connection;
>  import java.sql.PreparedStatement;
> +import java.sql.ResultSet;
>  import java.sql.SQLException;
>  import java.util.ArrayList;
>  import java.util.Arrays;
> @@ -157,7 +158,7 @@
>      /**
>       * Executes the filter as a SQL query.
>       */
> -    private static class SQLExecutor
> +    protected static class SQLExecutor
>          extends AbstractExecutor {
>
>          private final ClassMetaData _meta;
> @@ -224,20 +225,14 @@
>
>              PreparedStatement stmnt = null;
>              try {
> -                stmnt = buf.prepareCall(conn);
> +                stmnt = prepareCall(conn, buf);
>
>                  int index = 0;
> -                for (Iterator i = paramList.iterator(); i.hasNext();)
> +                for (Iterator i = paramList.iterator(); i.hasNext() &&
> +                    stmnt != null;)
>                      dict.setUnknown(stmnt, ++index, i.next(), null);
>
> -                int count = 0;
> -                if (_call && stmnt.execute() == false) {
> -                    count = stmnt.getUpdateCount();
> -                }
> -                else {
> -                    // native insert, update, delete
> -                    count = stmnt.executeUpdate();
> -                }
> +                int count = executeUpdate(store, conn, stmnt, buf);
>                  return Numbers.valueOf(count);
>              } catch (SQLException se) {
>                  if (stmnt != null)
> @@ -276,20 +271,23 @@
>              try {
>                  // use the right method depending on sel vs. proc, lrs setting
>                  if (_select && !range.lrs)
> -                    stmnt = buf.prepareStatement(conn);
> +                    stmnt = prepareStatement(conn, buf);
>                  else if (_select)
> -                    stmnt = buf.prepareStatement(conn, fetch, -1, -1);
> +                    stmnt = prepareStatement(conn, buf, fetch, -1, -1);
>                  else if (!range.lrs)
> -                    stmnt = buf.prepareCall(conn);
> +                    stmnt = prepareCall(conn, buf);
>                  else
> -                    stmnt = buf.prepareCall(conn, fetch, -1, -1);
> +                    stmnt = prepareCall(conn, buf, fetch, -1, -1);
>
>                  int index = 0;
> -                for (Iterator i = paramList.iterator(); i.hasNext();)
> +                for (Iterator i = paramList.iterator(); i.hasNext() &&
> +                    stmnt != null;)
>                      dict.setUnknown(stmnt, ++index, i.next(), null);
>
> -                ResultSetResult res = new ResultSetResult(conn, stmnt,
> -                    stmnt.executeQuery(), store);
> +                ResultSet rs = executeQuery(store, conn, stmnt, buf, paramList);
> +                ResultSetResult res = stmnt != null ?
> +                    new ResultSetResult(conn, stmnt, rs, store) :
> +                    new ResultSetResult(conn, rs, dict);
>                  if (_resultMapping != null)
>                      rop = new MappedQueryResultObjectProvider(_resultMapping,
>                          store, fetch, res);
> @@ -318,6 +316,72 @@
>
>          public boolean isPacking(StoreQuery q) {
>              return q.getContext().getCandidateType() == null;
> +        }
> +
> +        /**
> +         * This method is to provide override for non-JDBC or JDBC-like
> +         * implementation of preparing call statement.
> +         */
> +        protected PreparedStatement prepareCall(Connection conn, SQLBuffer buf)
> +            throws SQLException {
> +            return buf.prepareCall(conn);
> +        }
> +
> +        /**
> +         * This method is to provide override for non-JDBC or JDBC-like
> +         * implementation of executing update.
> +         */
> +        protected int executeUpdate(JDBCStore store, Connection conn,
> +            PreparedStatement stmnt, SQLBuffer buf)
> +            throws SQLException {
> +            int count = 0;
> +            if (_call && stmnt.execute() == false) {
> +                count = stmnt.getUpdateCount();
> +            }
> +            else {
> +                // native insert, update, delete
> +                count = stmnt.executeUpdate();
> +            }
> +            return count;
> +        }
> +
> +        /**
> +         * This method is to provide override for non-JDBC or JDBC-like
> +         * implementation of preparing call statement.
> +         */
> +        protected PreparedStatement prepareCall(Connection conn, SQLBuffer buf,
> +            JDBCFetchConfiguration fetch, int rsType, int rsConcur)
> +            throws SQLException {
> +            return buf.prepareCall(conn, fetch, rsType, rsConcur);
> +        }
> +
> +        /**
> +         * This method is to provide override for non-JDBC or JDBC-like
> +         * implementation of preparing statement.
> +         */
> +        protected PreparedStatement prepareStatement(Connection conn,
> +            SQLBuffer buf) throws SQLException {
> +            return buf.prepareStatement(conn);
> +        }
> +
> +        /**
> +         * This method is to provide override for non-JDBC or JDBC-like
> +         * implementation of preparing statement.
> +         */
> +        protected PreparedStatement prepareStatement(Connection conn,
> +            SQLBuffer buf, JDBCFetchConfiguration fetch, int rsType,
> +            int rsConcur) throws SQLException {
> +            return buf.prepareStatement(conn, fetch, rsType, rsConcur);
> +        }
> +
> +        /**
> +         * This method is to provide override for non-JDBC or JDBC-like
> +         * implementation of executing query.
> +         */
> +        protected ResultSet executeQuery(JDBCStore store, Connection conn,
> +            PreparedStatement stmnt, SQLBuffer buf, List paramList)
> +            throws SQLException {
> +            return stmnt.executeQuery();
>          }
>      }
>  }
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java Wed Jan 23 17:33:48 2008
> @@ -30,7 +30,6 @@
>  import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
>  import org.apache.openjpa.jdbc.meta.ClassMapping;
>  import org.apache.openjpa.jdbc.schema.Column;
> -import org.apache.openjpa.jdbc.schema.Index;
>  import org.apache.openjpa.jdbc.schema.PrimaryKey;
>  import org.apache.openjpa.jdbc.schema.Schema;
>  import org.apache.openjpa.jdbc.schema.SchemaGroup;
> @@ -38,6 +37,7 @@
>  import org.apache.openjpa.jdbc.schema.Schemas;
>  import org.apache.openjpa.jdbc.schema.Table;
>  import org.apache.openjpa.jdbc.sql.DBDictionary;
> +import org.apache.openjpa.jdbc.sql.RowImpl;
>  import org.apache.openjpa.jdbc.sql.SQLBuffer;
>  import org.apache.openjpa.jdbc.sql.SQLExceptions;
>  import org.apache.openjpa.lib.conf.Configurable;
> @@ -431,8 +431,8 @@
>
>          PreparedStatement stmnt = null;
>          try {
> -            stmnt = insert.prepareStatement(conn);
> -            stmnt.executeUpdate();
> +            stmnt = prepareStatement(conn, insert);
> +            executeUpdate(_conf, conn, stmnt, insert, RowImpl.ACTION_INSERT);
>          } finally {
>              if (stmnt != null)
>                  try { stmnt.close(); } catch (SQLException se) {}
> @@ -464,17 +464,16 @@
>                  null, false, dict.supportsSelectForUpdate, 0, Long.MAX_VALUE,
>                  false, true);
>
> -        PreparedStatement stmnt = select.prepareStatement(conn);
> +        PreparedStatement stmnt = prepareStatement(conn, select);
>          ResultSet rs = null;
>          try {
> -            rs = stmnt.executeQuery();
> -            if (!rs.next())
> -                return -1;
> -            return dict.getLong(rs, 1);
> +            rs = executeQuery(_conf, conn, stmnt, select);
> +            return getSequence(rs, dict);
>          } finally {
>              if (rs != null)
>                  try { rs.close(); } catch (SQLException se) {}
> -            try { stmnt.close(); } catch (SQLException se) {}
> +            if (stmnt != null)
> +                try { stmnt.close(); } catch (SQLException se) {}
>          }
>      }
>
> @@ -522,8 +521,8 @@
>                      append(_seqColumn).append(" = ").
>                      appendValue(Numbers.valueOf(cur), _seqColumn);
>
> -                stmnt = upd.prepareStatement(conn);
> -                updates = stmnt.executeUpdate();
> +                stmnt = prepareStatement(conn, upd);
> +                updates = executeUpdate(_conf, conn, stmnt, upd, RowImpl.ACTION_UPDATE);
>              } finally {
>                  if (rs != null)
>                      try { rs.close(); } catch (SQLException se) {}
> @@ -703,5 +702,42 @@
>
>          public long seq = 1L;
>          public long max = 0L;
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of preparing statement.
> +     */
> +    protected PreparedStatement prepareStatement(Connection conn, SQLBuffer buf)
> +        throws SQLException {
> +        return buf.prepareStatement(conn);
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of executing update.
> +     */
> +    protected int executeUpdate(JDBCConfiguration conf, Connection conn,
> +        PreparedStatement stmnt, SQLBuffer buf, int opcode) throws SQLException {
> +        return stmnt.executeUpdate();
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of executing query.
> +     */
> +    protected ResultSet executeQuery(JDBCConfiguration conf, Connection conn,
> +        PreparedStatement stmnt, SQLBuffer buf) throws SQLException {
> +        return stmnt.executeQuery();
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of getting sequence from the result set.
> +     */
> +    protected long getSequence(ResultSet rs, DBDictionary dict) throws SQLException {
> +        if (rs == null || !rs.next())
> +            return -1;
> +        return dict.getLong(rs, 1);
>      }
>  }
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java Wed Jan 23 17:33:48 2008
> @@ -49,7 +49,7 @@
>   *
>   * @author Abe White
>   */
> -class PCPath
> +public class PCPath
>      extends AbstractVal
>      implements JDBCPath {
>
> @@ -549,7 +549,7 @@
>      /**
>       * Expression state.
>       */
> -    private static class PathExpState
> +    public static class PathExpState
>          extends ExpState {
>
>          public FieldMapping field = null;
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java Wed Jan 23 17:33:48 2008
> @@ -93,7 +93,7 @@
>      /**
>       * Expression state.
>       */
> -    private static class ParamExpState
> +    public static class ParamExpState
>          extends ConstExpState {
>
>          public Object sqlValue = null;
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java Wed Jan 23 17:33:48 2008
> @@ -87,7 +87,6 @@
>  import org.apache.openjpa.kernel.Filters;
>  import org.apache.openjpa.kernel.OpenJPAStateManager;
>  import org.apache.openjpa.kernel.exps.Path;
> -import org.apache.openjpa.kernel.exps.Literal;
>  import org.apache.openjpa.lib.conf.Configurable;
>  import org.apache.openjpa.lib.conf.Configuration;
>  import org.apache.openjpa.lib.jdbc.ConnectionDecorator;
> @@ -1982,7 +1981,7 @@
>              ExpState state = val.initialize(sel, ctx, 0);
>              // JDBC Paths are always PCPaths; PCPath implements Val
>              ExpState pathState = ((Val) path).initialize(sel, ctx, 0);
> -            val.calculateValue(sel, ctx, state, (Val) path, pathState);
> +            calculateValue(val, sel, ctx, state, path, pathState);
>
>              // append the value with a null for the Select; i
>              // indicates that the
> @@ -3476,7 +3475,7 @@
>          if (str == null)
>              return new Sequence[0];
>
> -        PreparedStatement stmnt = conn.prepareStatement(str);
> +        PreparedStatement stmnt = prepareStatement(conn, str);
>          ResultSet rs = null;
>          try {
>              int idx = 1;
> @@ -3485,21 +3484,19 @@
>              if (sequenceName != null)
>                  stmnt.setString(idx++, sequenceName);
>
> -            rs = stmnt.executeQuery();
> -            List seqList = new ArrayList();
> -            while (rs.next())
> -                seqList.add(newSequence(rs));
> -            return (Sequence[]) seqList.toArray(new Sequence[seqList.size()]);
> -        } finally {
> +            rs = executeQuery(conn, stmnt, str);
> +            return getSequence(rs);
> +         } finally {
>              if (rs != null)
>                  try {
>                      rs.close();
>                  } catch (SQLException se) {
>                  }
> -            try {
> -                stmnt.close();
> -            } catch (SQLException se) {
> -            }
> +            if (stmnt != null)
> +                try {
> +                    stmnt.close();
> +                } catch (SQLException se) {
> +                }
>          }
>      }
>
> @@ -3880,20 +3877,16 @@
>              });
>          }
>
> -        PreparedStatement stmnt = conn.prepareStatement(query);
> +        PreparedStatement stmnt = prepareStatement(conn, query);
>          ResultSet rs = null;
>          try {
> -            rs = stmnt.executeQuery();
> -            if (!rs.next())
> -                throw new StoreException(_loc.get("no-genkey"));
> -            Object key = rs.getObject(1);
> -            if (key == null)
> -                log.warn(_loc.get("invalid-genkey", col));
> -            return key;
> +            rs = executeQuery(conn, stmnt, query);
> +            return getKey(rs, col);
>          } finally {
>              if (rs != null)
>                  try { rs.close(); } catch (SQLException se) {}
> -            try { stmnt.close(); } catch (SQLException se) {}
> +            if (stmnt != null)
> +                try { stmnt.close(); } catch (SQLException se) {}
>          }
>      }
>
> @@ -4277,4 +4270,55 @@
>              OpenJPAStateManager  sm, ClassMapping cmd ) {
>          return disableBatch;
>      }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of executing query.
> +     */
> +    protected ResultSet executeQuery(Connection conn, PreparedStatement stmnt, String sql
> +        ) throws SQLException {
> +        return stmnt.executeQuery();
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of preparing statement.
> +     */
> +    protected PreparedStatement prepareStatement(Connection conn, String sql)
> +        throws SQLException {
> +        return conn.prepareStatement(sql);
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of getting sequence from the result set.
> +     */
> +    protected Sequence[] getSequence(ResultSet rs) throws SQLException {
> +        List seqList = new ArrayList();
> +        while (rs != null && rs.next())
> +            seqList.add(newSequence(rs));
> +        return (Sequence[]) seqList.toArray(new Sequence[seqList.size()]);
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of getting key from the result set.
> +     */
> +    protected Object getKey (ResultSet rs, Column col) throws SQLException {
> +        if (!rs.next())
> +            throw new StoreException(_loc.get("no-genkey"));
> +        Object key = rs.getObject(1);
> +        if (key == null)
> +            log.warn(_loc.get("invalid-genkey", col));
> +        return key;
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of calculating value.
> +     */
> +    protected void calculateValue(Val val, Select sel, ExpContext ctx,
> +        ExpState state, Path path, ExpState pathState) {
> +        val.calculateValue(sel, ctx, state, (Val) path, pathState);
> +    }
>  }
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java Wed Jan 23 17:33:48 2008
> @@ -92,6 +92,17 @@
>      }
>
>      /**
> +     * Constructor.
> +     */
> +    public ResultSetResult(Connection conn,
> +        ResultSet rs, DBDictionary dict) {
> +        _conn = conn;
> +        _stmnt = null;
> +        _rs = rs;
> +        _dict = dict;
> +    }
> +
> +    /**
>       * JDBC 2 constructor. Relies on being able to retrieve the statement
>       * from the result set, and the connection from the statement.
>       */
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/RowImpl.java Wed Jan 23 17:33:48 2008
> @@ -20,7 +20,6 @@
>
>  import java.io.InputStream;
>  import java.io.Reader;
> -import java.lang.reflect.Method;
>  import java.math.BigDecimal;
>  import java.math.BigInteger;
>  import java.sql.Array;
> @@ -57,10 +56,10 @@
>  public class RowImpl
>      implements Row, Cloneable {
>
> -    protected static final Object NULL = new Object();
> +    public static final Object NULL = new Object();
>      protected static final int VALID = 2 << 0;
>
> -    private static final int RAW = Integer.MIN_VALUE;
> +    public static final int RAW = Integer.MIN_VALUE;
>
>      protected byte flags = 0;
>      private final Column[] _cols;
> @@ -949,5 +948,13 @@
>          System.arraycopy(_types, start, row._types, start, len);
>          if (isValid())
>              row.setValid(true);
> +    }
> +
> +    public Object[] getVals() {
> +        return _vals;
> +    }
> +
> +    public int[] getTypes() {
> +        return _types;
>      }
>  }
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java Wed Jan 23 17:33:48 2008
> @@ -641,4 +641,12 @@
>              return sub;
>          }
>      }
> +
> +    public void setParameters(List params) {
> +        _params = params;
> +    }
> +
> +    public List getColumns() {
> +        return _cols;
> +    }
>  }
>
> Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java (original)
> +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java Wed Jan 23 17:33:48 2008
> @@ -297,10 +297,11 @@
>          try {
>              SQLBuffer sql = toSelectCount();
>              conn = store.getConnection();
> -            stmnt = sql.prepareStatement(conn);
> -            rs = stmnt.executeQuery();
> -            rs.next();
> -            return rs.getInt(1);
> +            stmnt = prepareStatement(conn, sql, null,
> +                ResultSet.TYPE_FORWARD_ONLY,
> +                ResultSet.CONCUR_READ_ONLY, false);
> +            rs = executeQuery(conn, stmnt, sql, false, store);
> +            return getCount(rs);
>          } finally {
>              if (rs != null)
>                  try { rs.close(); } catch (SQLException se) {}
> @@ -342,31 +343,21 @@
>          }
>
>          SQLBuffer sql = toSelect(forUpdate, fetch);
> -        int rsType = (isLRS() && supportsRandomAccess(forUpdate))
> +        boolean isLRS = isLRS();
> +        int rsType = (isLRS && supportsRandomAccess(forUpdate))
>              ? -1 : ResultSet.TYPE_FORWARD_ONLY;
>          Connection conn = store.getConnection();
>          PreparedStatement stmnt = null;
>          ResultSet rs = null;
>          try {
> -            if (isLRS())
> -                stmnt = sql.prepareStatement(conn, fetch, rsType, -1);
> +            if (isLRS)
> +                stmnt = prepareStatement(conn, sql, fetch, rsType, -1, true);
>              else
> -                stmnt = sql.prepareStatement(conn, rsType, -1);
> -
> -            // if this is a locking select and the lock timeout is greater than
> -            // the configured query timeout, use the lock timeout
> -            if (forUpdate && _dict.supportsQueryTimeout && fetch != null
> -                && fetch.getLockTimeout() > stmnt.getQueryTimeout() * 1000) {
> -                int timeout = fetch.getLockTimeout();
> -                if (timeout < 1000) {
> -                    timeout = 1000;
> -                    Log log = _conf.getLog(JDBCConfiguration.LOG_JDBC);
> -                    if (log.isWarnEnabled())
> -                        log.warn(_loc.get("millis-query-timeout"));
> -                }
> -                stmnt.setQueryTimeout(timeout / 1000);
> -            }
> -            rs = stmnt.executeQuery();
> +                stmnt = prepareStatement(conn, sql, null, rsType, -1, false);
> +
> +            setTimeout(stmnt, forUpdate, fetch);
> +
> +            rs = executeQuery(conn, stmnt, sql, isLRS, store);
>          } catch (SQLException se) {
>              // clean up statement
>              if (stmnt != null)
> @@ -375,17 +366,8 @@
>              throw se;
>          }
>
> -        SelectResult res = new SelectResult(conn, stmnt, rs, _dict);
> -        res.setSelect(this);
> -        res.setStore(store);
> -        res.setLocking(forUpdate);
> -        try {
> -            addEagerResults(res, this, store, fetch);
> -        } catch (SQLException se) {
> -            res.close();
> -            throw se;
> -        }
> -        return res;
> +        return getEagerResult(conn, stmnt, rs, store, fetch, forUpdate,
> +            sql.getSQL());
>      }
>
>      /**
> @@ -421,6 +403,80 @@
>              }
>              eager.put(entry.getKey(), eres);
>          }
> +    }
> +
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of preparing statement.
> +     */
> +    protected PreparedStatement prepareStatement(Connection conn,
> +        SQLBuffer sql, JDBCFetchConfiguration fetch, int rsType,
> +        int rsConcur, boolean isLRS) throws SQLException {
> +        if (fetch == null)
> +            return sql.prepareStatement(conn, rsType, rsConcur);
> +        else
> +            return sql.prepareStatement(conn, fetch, rsType, -1);
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of setting query timeout.
> +     */
> +    protected void setTimeout(PreparedStatement stmnt, boolean forUpdate,
> +        JDBCFetchConfiguration fetch) throws SQLException {
> +        // if this is a locking select and the lock timeout is greater than
> +        // the configured query timeout, use the lock timeout
> +        if (forUpdate && _dict.supportsQueryTimeout && fetch != null
> +            && fetch.getLockTimeout() > stmnt.getQueryTimeout() * 1000) {
> +            int timeout = fetch.getLockTimeout();
> +            if (timeout < 1000) {
> +                timeout = 1000;
> +                Log log = _conf.getLog(JDBCConfiguration.LOG_JDBC);
> +                if (log.isWarnEnabled())
> +                    log.warn(_loc.get("millis-query-timeout"));
> +            }
> +            stmnt.setQueryTimeout(timeout / 1000);
> +        }
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of executing query.
> +     */
> +    protected ResultSet executeQuery(Connection conn, PreparedStatement stmnt,
> +        SQLBuffer sql, boolean isLRS, JDBCStore store) throws SQLException {
> +        return stmnt.executeQuery();
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of getting count from the result set.
> +     */
> +    protected int getCount(ResultSet rs) throws SQLException {
> +        rs.next();
> +        return rs.getInt(1);
> +    }
> +
> +    /**
> +     * This method is to provide override for non-JDBC or JDBC-like
> +     * implementation of executing eager selects.
> +     */
> +    protected Result getEagerResult(Connection conn,
> +        PreparedStatement stmnt, ResultSet rs, JDBCStore store,
> +        JDBCFetchConfiguration fetch, boolean forUpdate, String sqlStr)
> +        throws SQLException {
> +        SelectResult res = new SelectResult(conn, stmnt, rs, _dict);
> +        res.setSelect(this);
> +        res.setStore(store);
> +        res.setLocking(forUpdate);
> +        try {
> +            addEagerResults(res, this, store, fetch);
> +        } catch (SQLException se) {
> +            res.close();
> +            throw se;
> +        }
> +        return res;
>      }
>
>      /////////////////////////
>
> Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Bootstrap.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Bootstrap.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Bootstrap.java (original)
> +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Bootstrap.java Wed Jan 23 17:33:48 2008
> @@ -39,7 +39,7 @@
>   */
>  public class Bootstrap {
>
> -    private static final Class[] FACTORY_ARGS =
> +    protected static final Class[] FACTORY_ARGS =
>          new Class[]{ ConfigurationProvider.class };
>
>      private static Localizer s_loc = Localizer.forPackage(Bootstrap.class);
> @@ -124,7 +124,7 @@
>          return (BrokerFactory) meth.invoke(null, new Object[]{ conf });
>      }
>
> -    private static String getFactoryClassName(ConfigurationProvider conf,
> +    protected static String getFactoryClassName(ConfigurationProvider conf,
>          ClassLoader loader) {
>          try {
>              return getFactoryClass(conf, loader).getName();
>
> Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
> +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Wed Jan 23 17:33:48 2008
> @@ -2420,10 +2420,7 @@
>              }
>
>              // make sure we don't already have the instance cached
> -            StateManagerImpl other = getStateManagerImplById(id, false);
> -            if (other != null && !other.isDeleted() && !other.isNew())
> -                throw new ObjectExistsException(_loc.get("cache-exists",
> -                    obj.getClass().getName(), id)).setFailedObject(obj);
> +            checkForDuplicateId(id, obj);
>
>              // if had embedded sm, null it
>              if (sm != null)
> @@ -3817,7 +3814,7 @@
>                      _cache.remove(id, sm);
>                      break;
>                  case STATUS_OID_ASSIGN:
> -                    _cache.assignObjectId(id, sm);
> +                    assignObjectId(_cache, id, sm);
>                      break;
>                  case STATUS_COMMIT_NEW:
>                      _cache.commitNew(id, sm);
> @@ -4699,5 +4696,24 @@
>                  }
>              };
>          }
> +    }
> +
> +    /**
> +     * Assign the object id to the cache. Exception will be
> +     * thrown if the id already exists in the cache.
> +     */
> +    protected void assignObjectId(Object cache, Object id,
> +        StateManagerImpl sm) {
> +        ((ManagedCache) cache).assignObjectId(id, sm);
> +    }
> +
> +    /**
> +     * This method makes sure we don't already have the instance cached
> +     */
> +    protected void checkForDuplicateId(Object id, Object obj) {
> +        StateManagerImpl other = getStateManagerImplById(id, false);
> +        if (other != null && !other.isDeleted() && !other.isNew())
> +            throw new ObjectExistsException(_loc.get("cache-exists",
> +                obj.getClass().getName(), id)).setFailedObject(obj);
>      }
>  }
>
> Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
> +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Wed Jan 23 17:33:48 2008
> @@ -3001,7 +3001,7 @@
>      /**
>       * Mark the field as loaded or unloaded.
>       */
> -    private void setLoaded(int field, boolean isLoaded) {
> +    public void setLoaded(int field, boolean isLoaded) {
>          // don't continue if loaded state is already correct; otherwise we
>          // can end up clearing _fieldImpl when we shouldn't
>          if (_loaded.get(field) == isLoaded)
>
> Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java?rev=614763&r1=614762&r2=614763&view=diff
> ==============================================================================
> --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java (original)
> +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java Wed Jan 23 17:33:48 2008
> @@ -22,8 +22,6 @@
>  import java.lang.instrument.IllegalClassFormatException;
>  import java.security.ProtectionDomain;
>  import java.util.Map;
> -import java.util.Map.Entry;
> -import java.util.Set;
>  import javax.persistence.EntityManager;
>  import javax.persistence.spi.ClassTransformer;
>  import javax.persistence.spi.PersistenceProvider;
> @@ -73,7 +71,7 @@
>       */
>      public OpenJPAEntityManagerFactory createEntityManagerFactory(String name,
>          String resource, Map m) {
> -        PersistenceProductDerivation pd = new PersistenceProductDerivation();
> +        PersistenceProductDerivation pd = newPersistenceProductDerivation();
>          try {
>              Object poolValue = Configurations.removeProperty(EMF_POOL, m);
>              ConfigurationProvider cp = pd.load(resource, name, m);
> @@ -101,7 +99,7 @@
>          }
>
>          if (poolValue == null || !((Boolean) poolValue).booleanValue())
> -            return Bootstrap.newBrokerFactory(cp, loader);
> +            return newBrokerFactory(cp, loader);
>          else
>              return Bootstrap.getBrokerFactory(cp, loader);
>      }
> @@ -201,4 +199,19 @@
>              return _trans.transform(cl, name, previousVersion, pd, bytes);
>          }
>         }
> +
> +    /**
> +     * Return a persistence product deviration with default setting.
> +     */
> +    public PersistenceProductDerivation newPersistenceProductDerivation() {
> +        return new PersistenceProductDerivation();
> +    }
> +
> +    /**
> +     * Return a broker factory for the given configuration and class loader.
> +     */
> +    public BrokerFactory newBrokerFactory(ConfigurationProvider cp,
> +        ClassLoader loader) {
> +        return Bootstrap.newBrokerFactory(cp, loader);
> +    }
>  }
>
>
>



-- 
Patrick Linskey
202 669 5907