You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by kw...@apache.org on 2006/09/18 23:58:05 UTC

svn commit: r447584 [5/8] - in /incubator/openjpa/sandboxes/OPENJPA-24: ./ openjpa-all/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-jdbc/src/main/java/org/apache/openjpa/jd...

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Trim.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Trim.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Trim.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Trim.java Mon Sep 18 14:57:52 2006
@@ -18,8 +18,6 @@
 import java.lang.Math;
 import java.sql.SQLException;
 
-import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
-import org.apache.openjpa.jdbc.kernel.JDBCStore;
 import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
 import org.apache.openjpa.jdbc.sql.DBDictionary;
 import org.apache.openjpa.jdbc.sql.Joins;
@@ -43,7 +41,6 @@
     private final Val _trimChar;
     private final Boolean _where;
     private ClassMetaData _meta = null;
-    private String _func = null;
 
     /**
      * Constructor. Provide the string to operate on.
@@ -62,10 +59,6 @@
         _meta = meta;
     }
 
-    public boolean isVariable() {
-        return false;
-    }
-
     public Class getType() {
         return String.class;
     }
@@ -73,119 +66,123 @@
     public void setImplicitType(Class type) {
     }
 
-    public void initialize(Select sel, JDBCStore store, boolean nullTest) {
-        _val.initialize(sel, store, false);
-
-        DBDictionary dict = store.getDBDictionary();
-        if (_where == null) {
-            _func = dict.trimBothFunction;
-            dict.assertSupport(_func != null, "TrimBothFunction");
-        } else if (_where.equals(Boolean.TRUE)) {
-            _func = dict.trimLeadingFunction;
-            dict.assertSupport(_func != null, "TrimLeadingFunction");
-        } else if (_where.equals(Boolean.FALSE)) {
-            _func = dict.trimTrailingFunction;
-            dict.assertSupport(_func != null, "TrimTrailingFunction");
-        }
+    public ExpState initialize(Select sel, ExpContext ctx, int flags) {
+        ExpState valueState =  _val.initialize(sel, ctx, 0);
+        ExpState charState = _trimChar.initialize(sel, ctx, 0);
+        return new TrimExpState(sel.and(valueState.joins, charState.joins), 
+            valueState, charState);
     }
 
-    public Joins getJoins() {
-        return _val.getJoins();
-    }
+    /**
+     * Expression state.
+     */
+    private static class TrimExpState
+        extends ExpState {
 
-    public Object toDataStoreValue(Object val, JDBCStore store) {
-        return val;
+        public final ExpState valueState;
+        public final ExpState charState;
+
+        public TrimExpState(Joins joins, ExpState valueState, 
+            ExpState charState) {
+            super(joins);
+            this.valueState = valueState;
+            this.charState = charState;
+        }
     }
 
-    public void select(Select sel, JDBCStore store, Object[] params,
-        boolean pks, JDBCFetchConfiguration fetch) {
-        sel.select(newSQLBuffer(sel, store, params, fetch), this);
+    public void select(Select sel, ExpContext ctx, ExpState state, 
+        boolean pks) {
+        sel.select(newSQLBuffer(sel, ctx, state), this);
     }
 
-    public void selectColumns(Select sel, JDBCStore store,
-        Object[] params, boolean pks, JDBCFetchConfiguration fetch) {
-        _val.selectColumns(sel, store, params, true, fetch);
+    public void selectColumns(Select sel, ExpContext ctx, ExpState state, 
+        boolean pks) {
+        TrimExpState tstate = (TrimExpState) state;
+        _val.selectColumns(sel, ctx, tstate.valueState, true);
+        _trimChar.selectColumns(sel, ctx, tstate.charState, true);
     }
 
-    public void groupBy(Select sel, JDBCStore store, Object[] params,
-        JDBCFetchConfiguration fetch) {
-        sel.groupBy(newSQLBuffer(sel, store, params, fetch));
+    public void groupBy(Select sel, ExpContext ctx, ExpState state) {
+        sel.groupBy(newSQLBuffer(sel, ctx, state));
     }
 
-    public void orderBy(Select sel, JDBCStore store, Object[] params,
-        boolean asc, JDBCFetchConfiguration fetch) {
-        sel.orderBy(newSQLBuffer(sel, store, params, fetch), asc, false);
+    public void orderBy(Select sel, ExpContext ctx, ExpState state, 
+        boolean asc) {
+        sel.orderBy(newSQLBuffer(sel, ctx, state), asc, false);
     }
 
-    private SQLBuffer newSQLBuffer(Select sel, JDBCStore store,
-        Object[] params, JDBCFetchConfiguration fetch) {
-        calculateValue(sel, store, params, null, fetch);
-        SQLBuffer buf = new SQLBuffer(store.getDBDictionary());
-        appendTo(buf, 0, sel, store, params, fetch);
-        clearParameters();
+    private SQLBuffer newSQLBuffer(Select sel, ExpContext ctx, ExpState state) {
+        calculateValue(sel, ctx, state, null, null);
+        SQLBuffer buf = new SQLBuffer(ctx.store.getDBDictionary());
+        appendTo(sel, ctx, state, buf, 0);
         return buf;
     }
 
-    public Object load(Result res, JDBCStore store,
-        JDBCFetchConfiguration fetch)
+    public Object load(ExpContext ctx, ExpState state, Result res)
         throws SQLException {
         return Filters.convert(res.getObject(this,
             JavaSQLTypes.JDBC_DEFAULT, null), getType());
     }
 
-    public void calculateValue(Select sel, JDBCStore store,
-        Object[] params, Val other, JDBCFetchConfiguration fetch) {
-        _val.calculateValue(sel, store, params, null, fetch);
+    public void calculateValue(Select sel, ExpContext ctx, ExpState state, 
+        Val other, ExpState otherState) {
+        TrimExpState tstate = (TrimExpState) state;
+        _val.calculateValue(sel, ctx, tstate.valueState, null, null);
+        _trimChar.calculateValue(sel, ctx, tstate.charState, null, null);
     }
 
-    public void clearParameters() {
-        _val.clearParameters();
-    }
-
-    public int length() {
+    public int length(Select sel, ExpContext ctx, ExpState state) {
         return 1;
     }
 
-    public void appendTo(SQLBuffer sql, int index, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch) {
-        _val.calculateValue(sel, store, params, _trimChar, fetch);
-        _trimChar.calculateValue(sel, store, params, _val, fetch);
-
-        int fromPart = _func.indexOf("{0}");
-        int charPart = _func.indexOf("{1}");
+    public void appendTo(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer sql, int index) {
+        DBDictionary dict = ctx.store.getDBDictionary();
+        String func;
+        if (_where == null) {
+            func = dict.trimBothFunction;
+            dict.assertSupport(func != null, "TrimBothFunction");
+        } else if (_where.booleanValue()) {
+            func = dict.trimLeadingFunction;
+            dict.assertSupport(func != null, "TrimLeadingFunction");
+        } else {
+            func = dict.trimTrailingFunction;
+            dict.assertSupport(func != null, "TrimTrailingFunction");
+        }
 
+        int fromPart = func.indexOf("{0}");
+        int charPart = func.indexOf("{1}");
         if (charPart == -1)
-            charPart = _func.length();
-
-        String part1 = _func.substring(0, Math.min(fromPart, charPart));
-
-        String part2 = _func.substring(Math.min(fromPart, charPart) + 3,
+            charPart = func.length();
+        String part1 = func.substring(0, Math.min(fromPart, charPart));
+        String part2 = func.substring(Math.min(fromPart, charPart) + 3,
             Math.max(fromPart, charPart));
-
         String part3 = null;
-        if (charPart != _func.length())
-            part3 = _func.substring(Math.max(fromPart, charPart) + 3);
+        if (charPart != func.length())
+            part3 = func.substring(Math.max(fromPart, charPart) + 3);
 
+        TrimExpState tstate = (TrimExpState) state;
         sql.append(part1);
-        (fromPart < charPart ? _val : _trimChar).
-            appendTo(sql, 0, sel, store, params, fetch);
+        if (fromPart < charPart)
+            _val.appendTo(sel, ctx, tstate.valueState, sql, 0);
+        else 
+            _trimChar.appendTo(sel, ctx, tstate.charState, sql, 0);
         sql.append(part2);
 
-        if (charPart != _func.length()) {
-            (fromPart > charPart ? _val : _trimChar).
-                appendTo(sql, 0, sel, store, params, fetch);
+        if (charPart != func.length()) {
+            if (fromPart > charPart)
+                _val.appendTo(sel, ctx, tstate.valueState, sql, 0);
+            else
+                _trimChar.appendTo(sel, ctx, tstate.charState, sql, 0);
             sql.append(part3);
         } else {
             // since the trim statement did not specify the token for
             // where to specify the trim char (denoted by "{1}"),
             // we do not have the ability to trim off non-whitespace
             // characters; throw an exception when we attempt to do so
-            if (!(_trimChar instanceof Literal)
-                || String.valueOf(((Literal) _trimChar).getValue()).
-                trim().length() != 0) {
-                store.getDBDictionary().assertSupport(false,
-                    "TrimNonWhitespaceCharacters");
-            }
+            if (!(_trimChar instanceof Const) || String.valueOf(((Const) 
+                _trimChar).getValue(ctx,tstate.charState)).trim().length() != 0)
+                dict.assertSupport(false, "TrimNonWhitespaceCharacters");
         }
     }
 

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java Mon Sep 18 14:57:52 2006
@@ -17,10 +17,7 @@
 
 import java.sql.SQLException;
 
-import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
-import org.apache.openjpa.jdbc.kernel.JDBCStore;
 import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
-import org.apache.openjpa.jdbc.sql.Joins;
 import org.apache.openjpa.jdbc.sql.Result;
 import org.apache.openjpa.jdbc.sql.SQLBuffer;
 import org.apache.openjpa.jdbc.sql.Select;
@@ -47,7 +44,7 @@
         _val = val;
     }
 
-    protected Val getVal() {
+    protected Val getValue() {
         return _val;
     }
 
@@ -59,10 +56,6 @@
         _meta = meta;
     }
 
-    public boolean isVariable() {
-        return false;
-    }
-
     public Class getType() {
         if (_cast != null)
             return _cast;
@@ -73,74 +66,62 @@
         _cast = type;
     }
 
-    public void initialize(Select sel, JDBCStore store, boolean nullTest) {
-        _val.initialize(sel, store, false);
-    }
-
-    public Joins getJoins() {
-        return _val.getJoins();
+    public ExpState initialize(Select sel, ExpContext ctx, int flags) {
+        return initializeValue(sel, ctx, flags);
     }
 
-    public Object toDataStoreValue(Object val, JDBCStore store) {
-        return val;
+    protected ExpState initializeValue(Select sel, ExpContext ctx, int flags) {
+        return _val.initialize(sel, ctx, flags);
     }
 
-    public void select(Select sel, JDBCStore store, Object[] params,
-        boolean pks, JDBCFetchConfiguration fetch) {
-        sel.select(newSQLBuffer(sel, store, params, fetch), this);
+    public void select(Select sel, ExpContext ctx, ExpState state, 
+        boolean pks) {
+        sel.select(newSQLBuffer(sel, ctx, state), this);
         if (isAggregate())
             sel.setAggregate(true);
     }
 
-    public void selectColumns(Select sel, JDBCStore store,
-        Object[] params, boolean pks, JDBCFetchConfiguration fetch) {
-        _val.selectColumns(sel, store, params, true, fetch);
+    public void selectColumns(Select sel, ExpContext ctx, ExpState state, 
+        boolean pks) {
+        _val.selectColumns(sel, ctx, state, true);
     }
 
-    public void groupBy(Select sel, JDBCStore store, Object[] params,
-        JDBCFetchConfiguration fetch) {
-        sel.groupBy(newSQLBuffer(sel, store, params, fetch));
+    public void groupBy(Select sel, ExpContext ctx, ExpState state) {
+        sel.groupBy(newSQLBuffer(sel, ctx, state));
     }
 
-    public void orderBy(Select sel, JDBCStore store, Object[] params,
-        boolean asc, JDBCFetchConfiguration fetch) {
-        sel.orderBy(newSQLBuffer(sel, store, params, fetch), asc, false);
+    public void orderBy(Select sel, ExpContext ctx, ExpState state, 
+        boolean asc) {
+        sel.orderBy(newSQLBuffer(sel, ctx, state), asc, false);
     }
 
-    private SQLBuffer newSQLBuffer(Select sel, JDBCStore store,
-        Object[] params, JDBCFetchConfiguration fetch) {
-        calculateValue(sel, store, params, null, fetch);
-        SQLBuffer buf = new SQLBuffer(store.getDBDictionary());
-        appendTo(buf, 0, sel, store, params, fetch);
-        clearParameters();
+    private SQLBuffer newSQLBuffer(Select sel, ExpContext ctx, ExpState state) {
+        calculateValue(sel, ctx, state, null, null);
+        SQLBuffer buf = new SQLBuffer(ctx.store.getDBDictionary());
+        appendTo(sel, ctx, state, buf, 0);
         return buf;
     }
 
-    public Object load(Result res, JDBCStore store,
-        JDBCFetchConfiguration fetch)
+    public Object load(ExpContext ctx, ExpState state, Result res)
         throws SQLException {
         return Filters.convert(res.getObject(this,
             JavaSQLTypes.JDBC_DEFAULT, null), getType());
     }
 
-    public void calculateValue(Select sel, JDBCStore store,
-        Object[] params, Val other, JDBCFetchConfiguration fetch) {
-        _val.calculateValue(sel, store, params, null, fetch);
-    }
-
-    public void clearParameters() {
-        _val.clearParameters();
+    public void calculateValue(Select sel, ExpContext ctx, ExpState state, 
+        Val other, ExpState otherState) {
+        _val.calculateValue(sel, ctx, state, null, null);
     }
 
-    public int length() {
+    public int length(Select sel, ExpContext ctx, ExpState state) {
         return 1;
     }
 
-    public void appendTo(SQLBuffer sql, int index, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch) {
+    public void appendTo(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer sql, int index) {
         sql.append(getOperator());
         sql.append("(");
-        _val.appendTo(sql, 0, sel, store, params, fetch);
+        _val.appendTo(sel, ctx, state, sql, 0);
         sql.append(")");
     }
 

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java Mon Sep 18 14:57:52 2006
@@ -36,64 +36,54 @@
     extends Value {
 
     /**
-     * Initialize the value. This method should recursively initialize any
-     * sub-values. It should also cache the {@link Joins} instance
-     * containing the joins for this value. No additional joins should be
-     * made after this call. The parent expression might modify these joins
-     * during its own initialization so that common joins are moved up the
-     * expression tree. These joins should not be included in the SQL
-     * appended through any of the <code>append</code> methods.
-     *
-     * @param sel used to create {@link Joins} instances
-     * @param store the store manager for the query
-     * @param nullTest if true, then this value will be compared
-     * to null or tested for emptiness
+     * Initialization flag indicating that this value will be compared to null.
      */
-    public void initialize(Select sel, JDBCStore store, boolean nullTest);
+    public final int NULL_CMP = 1;
 
     /**
-     * Return the joins for this value. These joins should be created
-     * and cached during the {@link #initialize} method. The parent
-     * expression might modify these joins during its own initialization so
-     * that common joins are moved up the expression tree.
+     * Initialization flag indicating to join into any relation path.
      */
-    public Joins getJoins();
+    public final int JOIN_REL = 2; 
+
+    /**
+     * Initialize the value. This method should recursively initialize any
+     * sub-values. 
+     */
+    public ExpState initialize(Select sel, ExpContext ctx, int flags);
 
     /**
      * Return the datastore value of the given object in the context of this
      * value.
      */
-    public Object toDataStoreValue(Object val, JDBCStore store);
+    public Object toDataStoreValue(Select sel, ExpContext ctx, ExpState state, 
+        Object val);
 
     /**
      * Select the data for this value.
      */
-    public void select(Select sel, JDBCStore store, Object[] params,
-        boolean pks, JDBCFetchConfiguration fetch);
+    public void select(Select sel, ExpContext ctx, ExpState state, boolean pks);
 
     /**
      * Select just the columns for this value.
      */
-    public void selectColumns(Select sel, JDBCStore store, Object[] params,
-        boolean pks, JDBCFetchConfiguration fetch);
+    public void selectColumns(Select sel, ExpContext ctx, ExpState state, 
+        boolean pks);
 
     /**
      * Group by this value.
      */
-    public void groupBy(Select sel, JDBCStore store, Object[] params,
-        JDBCFetchConfiguration fetch);
+    public void groupBy(Select sel, ExpContext ctx, ExpState state);
 
     /**
      * Order by this value.
      */
-    public void orderBy(Select sel, JDBCStore store, Object[] params,
-        boolean asc, JDBCFetchConfiguration fetch);
+    public void orderBy(Select sel, ExpContext ctx, ExpState state, 
+        boolean asc);
 
     /**
      * Load the data for this value.
      */
-    public Object load(Result res, JDBCStore store,
-        JDBCFetchConfiguration fetch)
+    public Object load(ExpContext ctx, ExpState state, Result res)
         throws SQLException;
 
     /**
@@ -102,55 +92,50 @@
      *
      * @param other the value being compared to, or null if not a comparison
      */
-    public void calculateValue(Select sel, JDBCStore store,
-        Object[] params, Val other, JDBCFetchConfiguration fetch);
-
-    /**
-     * Clear parameter values held by this value or its subcomponents.
-     * This method is called sometime after <code>calculateValue</code>.
-     */
-    public void clearParameters();
+    public void calculateValue(Select sel, ExpContext ctx, ExpState state, 
+        Val other, ExpState otherState);
 
     /**
      * Return the number of SQL elements in this value.
      */
-    public int length();
+    public int length(Select sel, ExpContext ctx, ExpState state);
 
     /**
      * Append the <code>index</code>th SQL element to the given buffer.
      */
-    public void appendTo(SQLBuffer sql, int index, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch);
+    public void appendTo(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer sql, 
+        int index);
 
     /**
      * Append the SQL testing whether this value is empty to the given buffer.
      */
-    public void appendIsEmpty(SQLBuffer sql, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch);
+    public void appendIsEmpty(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer sql);
 
     /**
      * Append the SQL testing whether this value is not empty to
      * the given buffer.
      */
-    public void appendIsNotEmpty(SQLBuffer sql, Select sel, JDBCStore store,
-        Object[] params, JDBCFetchConfiguration fetch);
+    public void appendIsNotEmpty(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer sql);
 
     /**
      * Append the SQL checking the size of this value.
      */
-    public void appendSize(SQLBuffer sql, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch);
+    public void appendSize(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer sql);
 
     /**
      * Append the SQL testing whether this value is null to the given buffer.
      */
-    public void appendIsNull(SQLBuffer sql, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch);
+    public void appendIsNull(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer sql);
 
     /**
      * Append the SQL testing whether this value is not null to the given
      * buffer.
      */
-    public void appendIsNotNull(SQLBuffer sql, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch);
+    public void appendIsNotNull(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer sql);
 }

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Variable.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Variable.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Variable.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Variable.java Mon Sep 18 14:57:52 2006
@@ -17,9 +17,6 @@
 
 import java.sql.SQLException;
 
-import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
-import org.apache.openjpa.jdbc.kernel.JDBCStore;
-import org.apache.openjpa.jdbc.sql.Joins;
 import org.apache.openjpa.jdbc.sql.Result;
 import org.apache.openjpa.jdbc.sql.SQLBuffer;
 import org.apache.openjpa.jdbc.sql.Select;
@@ -106,81 +103,66 @@
             _path.setImplicitType(type);
     }
 
-    public void initialize(Select sel, JDBCStore store, boolean nullTest) {
+    public ExpState initialize(Select sel, ExpContext ctx, int flags) {
         if (_path != null) {
             _path.addVariableAction(this);
-            _path.initialize(sel, store, nullTest);
-            _path.joinRelation();
+            return _path.initialize(sel, ctx, flags | JOIN_REL);
         }
+        return ExpState.NULL;
     }
 
-    public Joins getJoins() {
-        return (_path == null) ? null : _path.getJoins();
+    public void select(Select sel, ExpContext ctx, ExpState state, 
+        boolean pks) {
     }
 
-    public Object toDataStoreValue(Object val, JDBCStore store) {
-        return val;
+    public void selectColumns(Select sel, ExpContext ctx, ExpState state, 
+        boolean pks) {
     }
 
-    public void select(Select sel, JDBCStore store, Object[] params,
-        boolean pks, JDBCFetchConfiguration fetch) {
+    public void groupBy(Select sel, ExpContext ctx, ExpState state) {
     }
 
-    public void selectColumns(Select sel, JDBCStore store,
-        Object[] params, boolean pks, JDBCFetchConfiguration fetch) {
+    public void orderBy(Select sel, ExpContext ctx, ExpState state, 
+        boolean asc) {
     }
 
-    public void groupBy(Select sel, JDBCStore store, Object[] params,
-        JDBCFetchConfiguration fetch) {
-    }
-
-    public void orderBy(Select sel, JDBCStore store, Object[] params,
-        boolean asc, JDBCFetchConfiguration fetch) {
-    }
-
-    public Object load(Result res, JDBCStore store,
-        JDBCFetchConfiguration fetch)
+    public Object load(ExpContext ctx, ExpState state, Result res)
         throws SQLException {
         return null;
     }
 
-    public void calculateValue(Select sel, JDBCStore store,
-        Object[] params, Val other, JDBCFetchConfiguration fetch) {
-        if (_path != null)
-            _path.calculateValue(sel, store, params, other, fetch);
-    }
-
-    public void clearParameters() {
+    public void calculateValue(Select sel, ExpContext ctx, ExpState state, 
+        Val other, ExpState otherState) {
         if (_path != null)
-            _path.clearParameters();
+            _path.calculateValue(sel, ctx, state, other, otherState);
     }
 
-    public int length() {
+    public int length(Select sel, ExpContext ctx, ExpState state) {
         return 0;
     }
 
-    public void appendTo(SQLBuffer sql, int index, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch) {
+    public void appendTo(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer sql, int index) {
     }
 
-    public void appendIsEmpty(SQLBuffer sql, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch) {
+    public void appendIsEmpty(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer buf) {
     }
 
-    public void appendIsNotEmpty(SQLBuffer sql, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch) {
+    public void appendIsNotEmpty(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer buf) {
     }
 
-    public void appendSize(SQLBuffer sql, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch) {
+    public void appendSize(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer buf) {
     }
 
-    public void appendIsNull(SQLBuffer sql, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch) {
+    public void appendIsNull(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer buf) {
     }
 
-    public void appendIsNotNull(SQLBuffer sql, Select sel,
-        JDBCStore store, Object[] params, JDBCFetchConfiguration fetch) {
+    public void appendIsNotNull(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer buf) {
     }
 
     public void acceptVisit(ExpressionVisitor visitor) {

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorMappingInfo.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorMappingInfo.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorMappingInfo.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/DiscriminatorMappingInfo.java Mon Sep 18 14:57:52 2006
@@ -67,8 +67,8 @@
             return discrim.getMappingRepository().getMappingDefaults().
                 getDiscriminatorValue(discrim, adapt);
 
-        if (_value.length() > 0 &&
-            (_value.charAt(0) == '-' || Character.isDigit(_value.charAt(0)))) {
+        if (_value.length() > 0 && (_value.charAt(0) == '-' 
+            || Character.isDigit(_value.charAt(0)))) {
             try {
                 if (_value.indexOf('.') == -1)
                     return new Integer(_value);

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java Mon Sep 18 14:57:52 2006
@@ -335,7 +335,7 @@
 
     /**
      * Default base name for version identity columns, or null to the mapping's
-     * built-in name. This name may be combined with lock group names.
+     * built-in name.
      */
     public String getVersionColumnName() {
         return _versName;
@@ -343,7 +343,7 @@
 
     /**
      * Default base name for version identity columns, or null to the mapping's
-     * built-in name. This name may be combined with lock group names.
+     * built-in name.
      */
     public void setVersionColumnName(String versName) {
         _versName = versName;

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java Mon Sep 18 14:57:52 2006
@@ -1006,7 +1006,7 @@
                 return ImmutableValueHandler.getInstance();
             case JavaTypes.PC:
                 if (!val.getTypeMapping().isMapped()
-                    && useUntypedPCHandler(val))
+                    && useUntypedPCHandler(val)) 
                     return UntypedPCValueHandler.getInstance();
                 break;
             case JavaTypes.PC_UNTYPED:

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingTool.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingTool.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingTool.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingTool.java Mon Sep 18 14:57:52 2006
@@ -660,7 +660,8 @@
         ClassMapping mapping = repos.getMapping(cls, null, false);
         if (mapping != null)
             return mapping;
-        if (!validate || repos.getPersistenceAware(cls) != null)
+        if (!validate || cls.isInterface() 
+            || repos.getPersistenceAware(cls) != null)
             return null;
         throw new MetaDataException(_loc.get("no-meta", cls));
     }

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ColumnVersionStrategy.java Mon Sep 18 14:57:52 2006
@@ -138,7 +138,7 @@
 
         // set where and update conditions on row
         for (int i = 0; i < cols.length; i++) {
-            if (curVersion != null)
+            if (curVersion != null && sm.isVersionCheckRequired())
                 row.whereObject(cols[i], curVersion);
             if (vers.getColumnIO().isUpdatable(i, nextVersion == null))
                 row.setObject(cols[i], nextVersion);

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ContainerFieldStrategy.java Mon Sep 18 14:57:52 2006
@@ -29,7 +29,7 @@
  * An abstract container mapping that handles traversing the
  * join to examine the size of the relation.
  *
- * @author <a href="mailto:mprudhom@bea.com">Marc Prud'hommeaux</a>
+ * @author Marc Prud'hommeaux
  */
 public abstract class ContainerFieldStrategy
     extends AbstractFieldStrategy {

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java Mon Sep 18 14:57:52 2006
@@ -71,7 +71,8 @@
 
     public Object getJoinValue(OpenJPAStateManager sm, Column col,
         JDBCStore store) {
-        return Numbers.valueOf(((Id) sm.getObjectId()).getId());
+        Id id = (Id) sm.getObjectId();
+        return (id == null) ? null : id.getIdObject();
     }
 
     public void setAutoAssignedValue(OpenJPAStateManager sm, JDBCStore store,

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/InValueDiscriminatorStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/InValueDiscriminatorStrategy.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/InValueDiscriminatorStrategy.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/InValueDiscriminatorStrategy.java Mon Sep 18 14:57:52 2006
@@ -126,20 +126,29 @@
         if (subs.length == 0 && base.getJoinablePCSuperclassMapping() == null)
             return null;
 
-        // if not selecting subclasses, limit to just the given class
         Column col = disc.getColumns()[0];
         SQLBuffer sql = new SQLBuffer(sel.getConfiguration().
             getDBDictionaryInstance());
-        sql.append(sel.getColumnAlias(col, joins));
-        if (!subclasses || subs.length == 0)
+        boolean outer = joins != null && joins.isOuter();
+        if (outer)
+            sql.append("(");
+        String alias = sel.getColumnAlias(col, joins);
+        sql.append(alias);
+
+        // if not selecting subclasses, limit to just the given class
+        if (!outer && (!subclasses || subs.length == 0))
             return sql.append(" = ").appendValue(getDiscriminatorValue(base),
                 col);
 
+        if (outer)
+            sql.append(" IS ").appendValue(null).append(" OR ").append(alias);
         sql.append(" IN (");
         sql.appendValue(getDiscriminatorValue(base), col);
         for (int i = 0; i < subs.length; i++)
             sql.append(", ").appendValue(getDiscriminatorValue(subs[i]), col);
         sql.append(")");
+        if (outer)
+            sql.append(")");
         return sql;
     }
 }

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java Mon Sep 18 14:57:52 2006
@@ -246,9 +246,9 @@
         if (!io.isAnyUpdatable(fk, true))
             return;
 
+        // null inverse if not already enforced by fk
         if (field.getIndependentTypeMappings().length != 1)
             throw RelationStrategies.uninversable(field);
-
         Row row = rm.getAllRows(fk.getTable(), Row.ACTION_UPDATE);
         row.setForeignKey(fk, io, null);
         row.whereForeignKey(fk, sm);

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyInverseKeyFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyInverseKeyFieldStrategy.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyInverseKeyFieldStrategy.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyInverseKeyFieldStrategy.java Mon Sep 18 14:57:52 2006
@@ -223,10 +223,11 @@
         ValueMapping elem = field.getElementMapping();
         ColumnIO io = elem.getColumnIO();
         ForeignKey fk = elem.getForeignKey();
-        if (!io.isAnyUpdatable(fk, true))
+        if (!io.isAnyUpdatable(fk, true)) 
             return;
 
-        // null any existing inverse columns that refer to this obj
+        // if the fk doesn't enforce it, null any existing inverse columns 
+        // that refer to this obj
         assertInversable();
         Row row = rm.getAllRows(fk.getTable(), Row.ACTION_UPDATE);
         row.setForeignKey(fk, io, null);

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StateComparisonVersionStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StateComparisonVersionStrategy.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StateComparisonVersionStrategy.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StateComparisonVersionStrategy.java Mon Sep 18 14:57:52 2006
@@ -101,28 +101,30 @@
         // db values match our previous image
         FieldMapping[] fields = (FieldMapping[]) sm.getMetaData().getFields();
         Row row;
-        for (int i = 0, max = loaded.length(); i < max; i++) {
-            if (!loaded.get(i))
-                continue;
+        if (sm.isVersionCheckRequired()) {
+            for (int i = 0, max = loaded.length(); i < max; i++) {
+                if (!loaded.get(i))
+                    continue;
 
-            // update our next state image with the new field value
-            if (sm.getDirty().get(i) && !sm.getFlushed().get(i))
-                nextState[i] = sm.fetch(fields[i].getIndex());
+                // update our next state image with the new field value
+                if (sm.getDirty().get(i) && !sm.getFlushed().get(i))
+                    nextState[i] = sm.fetch(fields[i].getIndex());
 
-            // fetch the row for this field; if no row exists, then we can't
-            // add one because we have no updates to perform; that means we
-            // won't detect OL exceptions when another transaction changes
-            // fields that aren't in any of the same tables as fields that
-            // this transaction changed
-            row = rm.getRow(fields[i].getTable(), Row.ACTION_UPDATE,
-                sm, false);
-            if (row == null)
-                continue;
+                // fetch the row for this field; if no row exists, then we can't
+                // add one because we have no updates to perform; that means we
+                // won't detect OL exceptions when another transaction changes
+                // fields that aren't in any of the same tables as fields that
+                // this transaction changed
+                row = rm.getRow(fields[i].getTable(), Row.ACTION_UPDATE,
+                    sm, false);
+                if (row == null)
+                    continue;
 
-            // set WHERE criteria matching the previous state image so the
-            // update will fail if any changes have been made by another trans
-            fields[i].where(sm, store, rm, state[i]);
-            row.setFailedObject(sm.getManagedInstance());
+                // set WHERE criteria matching the previous state image so the
+                // update will fail for any changes made by another transaction
+                fields[i].where(sm, store, rm, state[i]);
+                row.setFailedObject(sm.getManagedInstance());
+            }
         }
         sm.setNextVersion(nextState);
     }

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java Mon Sep 18 14:57:52 2006
@@ -810,6 +810,10 @@
             return true;
         }
 
+        public boolean isOuter() {
+            return false;
+        }
+
         public Joins crossJoin(Table localTable, Table foreignTable) {
             return this;
         }

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractSQLServerDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractSQLServerDictionary.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractSQLServerDictionary.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractSQLServerDictionary.java Mon Sep 18 14:57:52 2006
@@ -33,7 +33,7 @@
     extends DBDictionary {
 
     public AbstractSQLServerDictionary() {
-        reservedWordSet.add("FILE");
+        reservedWordSet.addAll(Arrays.asList(new String[]{ "FILE", "INDEX" }));
         systemTableSet.add("DTPROPERTIES");
         validationSQL = "SELECT GETDATE()";
         rangePosition = RANGE_POST_DISTINCT;

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java Mon Sep 18 14:57:52 2006
@@ -59,6 +59,8 @@
 import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
 import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
 import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.kernel.exps.ExpContext;
+import org.apache.openjpa.jdbc.kernel.exps.ExpState;
 import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
 import org.apache.openjpa.jdbc.kernel.exps.Val;
 import org.apache.openjpa.jdbc.meta.ClassMapping;
@@ -1790,6 +1792,17 @@
             return sql;
         }
 
+        Table table = mapping.getTable();
+        String tableName = getFullName(table, false);
+
+        // only use a  subselect if the where is not empty; otherwise
+        // an unqualified delete or update will work
+        if (sel.getWhere() == null || sel.getWhere().isEmpty()) {
+            sql.append(tableName);
+            appendUpdates(sel, store, sql, params, updateParams, false);
+            return sql;
+        }
+
         // we need to use a subselect if we are to bulk delete where
         // the select includes multiple tables; if the database
         // doesn't support it, then we need to sigal this by returning null
@@ -1797,8 +1810,6 @@
             return null;
 
         Column[] pks = mapping.getPrimaryKeyColumns();
-        Table table = mapping.getTable();
-        String tableName = getFullName(table, false);
         sel.clearSelects();
         sel.setDistinct(true);
 
@@ -1851,6 +1862,8 @@
 
         // manually build up the SET clause for the UPDATE statement
         sql.append(" SET ");
+        ExpContext ctx = new ExpContext(store, params, 
+            store.getFetchConfiguration());
         for (Iterator i = updateParams.entrySet().iterator(); i.hasNext();) {
             Map.Entry next = (Map.Entry) i.next();
             FieldMetaData fmd = (FieldMetaData) next.getKey();
@@ -1859,15 +1872,15 @@
             Column col = ((FieldMapping) fmd).getColumns()[0];
             sql.append(col.getName());
             sql.append(" = ");
-            val.initialize(sel, store, false);
-            JDBCFetchConfiguration fetch = store.getFetchConfiguration();
-            val.calculateValue(sel, store, params, null, fetch);
+
+            ExpState state = val.initialize(sel, ctx, 0);
+            val.calculateValue(sel, ctx, state, null, null);
 
             // append the value with a null for the Select; i
             // indicates that the
-            for (int j = 0; j < val.length(); j++)
-                val.appendTo(sql, j, (allowAlias) ? sel : null, store, params, 
-                    fetch);
+            int length = val.length(sel, ctx, state);
+            for (int j = 0; j < length; j++)
+                val.appendTo((allowAlias) ? sel : null, ctx, state, sql, j);
 
             if (i.hasNext())
                 sql.append(", ");
@@ -3607,10 +3620,7 @@
         } catch (IOException ioe) {
             throw new GeneralException(ioe);
         } finally {
-            try {
-                in.close();
-            } catch (IOException e) {
-            }
+            try { in.close(); } catch (IOException e) {}
         }
 
         // add additional reserved words set by user

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/HSQLDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/HSQLDictionary.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/HSQLDictionary.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/HSQLDictionary.java Mon Sep 18 14:57:52 2006
@@ -214,6 +214,18 @@
         return cols;
     }
 
+    public void setDouble(PreparedStatement stmnt, int idx, double val,
+        Column col)
+        throws SQLException {
+        // HSQL has a bug where it cannot store a double if it is
+        // exactly the same as Long.MAX_VALUE or MIN_VALUE
+        if (val == Long.MAX_VALUE || val == Long.MIN_VALUE) {
+            stmnt.setLong(idx, (long)val);
+        } else  {
+            super.setDouble(stmnt, idx, val, col);
+        }
+    }
+
     public void setBigDecimal(PreparedStatement stmnt, int idx, BigDecimal val,
         Column col)
         throws SQLException {

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java Mon Sep 18 14:57:52 2006
@@ -32,6 +32,11 @@
     public boolean isEmpty();
 
     /**
+     * Whether this joins path results in outer joins.
+     */
+    public boolean isOuter();
+
+    /**
      * Perform a cross join on the given tables.
      */
     public Joins crossJoin(Table localTable, Table foreignTable);

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java Mon Sep 18 14:57:52 2006
@@ -810,6 +810,10 @@
             return sel.newJoins();
         }
 
+        public Joins newOuterJoins() {
+            return sel.newOuterJoins();
+        }
+
         public void append(SQLBuffer buf, Joins joins) {
             sel.append(buf, joins);
         }

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java Mon Sep 18 14:57:52 2006
@@ -135,6 +135,9 @@
         smallintTypeName = "NUMBER{0}";
         tinyintTypeName = "NUMBER{0}";
         longVarcharTypeName = "LONG";
+        binaryTypeName = "BLOB";
+        varbinaryTypeName = "BLOB";
+        longVarbinaryTypeName = "BLOB";
         timeTypeName = "DATE";
         varcharTypeName = "VARCHAR2{0}";
         fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java Mon Sep 18 14:57:52 2006
@@ -653,6 +653,11 @@
     public Joins newJoins();
 
     /**
+     * Return a new instance to use for outer joining.
+     */
+    public Joins newOuterJoins();
+
+    /**
      * Append the given joins to the given buffer.
      */
     public void append(SQLBuffer buf, Joins joins);

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java Mon Sep 18 14:57:52 2006
@@ -759,7 +759,7 @@
 
         // delegate to store manager to select in same order it loads result
         ((JDBCStoreManager) store).select(wrapper, mapping, subclasses, null,
-            null, fetch, eager, ident);
+            null, fetch, eager, ident, (_flags & OUTER) != 0);
 
         // reset
         if (hasJoins)
@@ -1626,6 +1626,10 @@
         return this;
     }
 
+    public Joins newOuterJoins() {
+        return ((PathJoins) newJoins()).setOuter(true);
+    }
+
     public void append(SQLBuffer buf, Joins joins) {
         if (joins == null || joins.isEmpty())
             return;
@@ -1744,10 +1748,9 @@
             return joins;
 
         // record that this is an outer join set, even if it's empty
-        PathJoins pj = (PathJoins) joins;
-        pj.setOuter(true);
-        if (joins.isEmpty())
-            return joins;
+        PathJoins pj = ((PathJoins) joins).setOuter(true);
+        if (pj.isEmpty())
+            return pj;
 
         Join join;
         Join rec;
@@ -1928,7 +1931,8 @@
         return false;
     }
 
-    public void setOuter(boolean outer) {
+    public PathJoins setOuter(boolean outer) {
+        return new SelectJoins(this).setOuter(true);
     }
 
     public boolean isDirty() {
@@ -1994,14 +1998,12 @@
      * Represents a SQL string selected with null id.
      */
     private static class NullId {
-
     }
 
     /**
      * Represents a placeholder SQL string.
      */
     private static class Placeholder {
-
     }
 
     /**
@@ -2269,7 +2271,8 @@
             return false;
         }
 
-        public void setOuter(boolean outer) {
+        public PathJoins setOuter(boolean outer) {
+            return this;
         }
 
         public boolean isDirty() {
@@ -2345,7 +2348,8 @@
             return false;
         }
 
-        public void setOuter(boolean outer) {
+        public PathJoins setOuter(boolean outer) {
+            return this;
         }
 
         public boolean isDirty() {
@@ -2452,8 +2456,9 @@
             return _outer;
         }
 
-        public void setOuter(boolean outer) {
+        public PathJoins setOuter(boolean outer) {
             _outer = outer;
+            return this;
         }
 
         public boolean isDirty() {
@@ -2797,14 +2802,9 @@
     extends Joins {
 
     /**
-     * Return whether this join set ended with an outer join.
-     */
-    public boolean isOuter();
-
-    /**
      * Mark this as an outer joins set.
      */
-    public void setOuter(boolean outer);
+    public PathJoins setOuter(boolean outer);
 
     /**
      * Return true if this instance has a path, any joins, or a variable.

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/localizer.properties
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/localizer.properties?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/localizer.properties (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/localizer.properties Mon Sep 18 14:57:52 2006
@@ -15,14 +15,12 @@
 	declarations.
 bad-targetfield: "{0}" has a column with target field "{1}", but that is not a \
 	primary key field of the related class.
-bad-col-lg-counts: Cannot synchronize mapping information: the number of \
-	version columns is not equal to the number of lock groups.
 no-joinable: You cannot join on column "{0}".  It is not managed by a mapping \
 	that supports joins.
 join-required: Missing table name for field "{0}".  This field cannot reside \
 	in the owning class table.
 bad-discrim-value: The declared discriminator value "{1}" for type "{0}" \
-	cannot be parsed as a number, though it starts with a digit.   
+	cannot be parsed as a number, though it starts with a digit.
 unexpected-cols: You have supplied columns for "{0}", but this mapping cannot \
 	have columns in this context.
 unexpected-index: "{0}" is marked as indexed, but OpenJPA does not support \
@@ -58,7 +56,7 @@
 	in the default fetch group.  You can only order on fields that will be \
 	selected when the related object is loaded.
 order-conflict: Field "{0}" declares both a synthetic ordering column and \
-	order-by values.  You cannot use both.  
+	order-by values.  You cannot use both.
 order-no-col-name: No order column name was given for "{0}".
 order-bad-col-name: "{0}" declares order column "{1}", but this column does \
 	not exist in table "{2}".
@@ -378,24 +376,14 @@
 custom-unused-props: The following customizer properties were not used in \
 	the reverse mapping process: {0}.
 reverse-type: Overriding type mapping for column of type name "{0}" to Java \
-	class "{1}". 
+	class "{1}".
 no-reverse-type: No overridden type mapping for column of type name "{0}".
 no-query-res: There is no query result mapping for "{0}" with name "{1}".
 null-path: Attempt to add a null or empty path to result type "{1}" in mapping \
-	"{0}". 
+	"{0}".
 bad-path: Result path "{2}" in result type "{1}" of mapping "{0}" contains \
 	invalid fields.
 untraversable-path: Result path "{2}" in result type "{1}" of mapping "{0}" \
 	attempts to traverse through a non-relation field.
 num-cols-path: Result path "{2}" in result type "{1}" of mapping "{0}" \
 	attempts to map a field that does not have exactly 1 column.
-lock-group-requires-perf-pack: Field "{0}" declares the lock-group extension. \
-	In order to use custom lock groups, you must have a performance pack or \
-	enterprise edition license. Contact sales@bea.com for details on \
-	upgrading your license.
-sub-lock-groups: Type "{0}" has a mapped superclass, and therefore cannot \
-	declare additional lock groups.  Use the "lock-groups" extension on the \
-	mapped superclass to declare any additional lock groups needed by this \
-	type.  {1}
-vers-mult-lock-groups: Type "{0}" cannot use a version field because it has \
-	multiple lock groups.

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties Mon Sep 18 14:57:52 2006
@@ -13,7 +13,7 @@
 cant-load: "{0}" is not a valid mapping. The related type has subclasses that \
 	are not reachable via joins, so OpenJPA must be able to construct an oid \
 	from the mapped foreign key.  But your foreign key does not represent all \
-	primary key values of the related type. 
+	primary key values of the related type.
 flush-virtual: Attempt to flush an unmapped object of type "{0}" with oid "{1}".
 cant-project-owned: "{0}" cannot be used in a projection, because it can only \
 	be loaded as part of its owning object.
@@ -45,7 +45,7 @@
 oid-not-joinable: Field "{0}" embedded within object id field "{1}" cannot be \
 	a primary key value.  Its mapping does not it to be a join target.
 flat-table: Type "{0}" uses a flat inheritance mapping, but declares a table \
-	name of "{1}", which does not match the superclass table "{2}".  
+	name of "{1}", which does not match the superclass table "{2}".
 not-string: Field "{0}" declares a string field mapping strategy, but is not \
 	a string field.
 not-primitive: Field "{0}" declares a primitive field mapping strategy, but \
@@ -58,7 +58,7 @@
 	not a char array field.
 not-serialized: Field "{0}" declares a blob mapping strategy, but the \
 	field''s value is not serialized.  Set the field''s "serialized" attribute \
-	to true.  
+	to true.
 not-relation: "{0}" declares a relation mapping strategy, but is not a \
 	direct, non-embedded relation to another persistence-capable object.
 not-elem-relation: "{0}" declares a to-many relation strategy, but its \
@@ -83,18 +83,16 @@
 	is mapped by another field.  Use an inverse key or join table mapping.
 not-mapped-by-key: Map field "{0}" is attempting to use an inverse key or join \
 	table mapping, but its key is not mapped by another field.  Use a map \
-	table mapping. 
+	table mapping.
 no-handler: Field "{0}" declares a handler-based mapping strategy, but no \
 	value handler is installed.
 auto-assign-handler: Attempt to use an auto-assigned column value in a handler \
 	with multiple columns.  To use an auto-assigned column value with field \
 	"{0}", you will have to write a custom field mapping that implements the \
 	org.apache.openjpa.jdbc.meta.Joinable interface.
-no-lock-groups: Type "{0}" does not have any fields that participate in \
-	optimistic locking.  Set its version strategy to "none".
 load-subs: Loading subclasses from discriminator column of "{0}".
 no-class-name: The discriminator column "{1}" for type "{1}" contains a null \
-	or empty value. 
+	or empty value.
 cant-init-subs: The discriminator for type "{0}" cannot compute the list of \
 	its subclasses on its own.  You should either use a discriminator strategy \
 	that has this ability (such as the class-name strategy), include the set \

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/schema/localizer.properties
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/schema/localizer.properties?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/schema/localizer.properties (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/schema/localizer.properties Mon Sep 18 14:57:52 2006
@@ -84,7 +84,7 @@
 add-seq: The sequence "{0}" was not added to the database.
 bad-col: Existing column "{0}" on table "{1}" is incompatible with the \
 	same column in the given schema definition. Existing column:\n{2}\
-	Given column:\n{3}	
+	Given column:\n{3}
 bad-pk: Existing primary key "{0}" on table "{1}" is incompatible with \
 	the same primary key in the given schema definition.
 bad-index: Existing index "{0}" on table "{1}" is incompatible with the \
@@ -128,5 +128,3 @@
 generating-foreign: Reading foreign keys for table "{1}"
 generating-sequences: Reading sequences for schema "{0}"
 no-custom-ds: use a custom DataSource
-max-pool-license: Your license only permits a maximum of {0} pooled \
-	connections; the connection pool will be configured accordingly.

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties Mon Sep 18 14:57:52 2006
@@ -92,13 +92,13 @@
 	The tables used in this select are: "{0}".  You should either configure \
 	your application to avoid multi-table selects, use optimistic locking, \
 	or set the "SimulateLocking" DBDictionary property to allow non-locking \
-	selects within pessimistic transactions. 
+	selects within pessimistic transactions.
 informix-cant-lock: Informix cannot perform FOR UPDATE selects on multiple \
 	tables, or when it is a SELECT DISTINCT.  The tables used in this select \
 	are: "{0}".  You should either configure your application to avoid \
 	multi-table/distinct selects, use optimistic locking, or set the \
 	"SimulateLocking" DBDictionary property to allow non-locking selects \
-	within pessimistic transactions. 
+	within pessimistic transactions.
 bad-param: The specified parameter of type "{0}" is not a valid query parameter.
 warn-generic: Your database configuration was not recognized as a supported \
 	OpenJPA database. The generic dictionary will be used, which may result in \
@@ -113,7 +113,7 @@
 	("{2}") that was not found.
 dd-lock-bug: This version of the DataDirect JDBC driver has a bug that \
 	prevents SELECT FOR UPDATE statements from working.  Please \
-	use version 3.2 or higher of the driver.	
+	use version 3.2 or higher of the driver.
 storage-restriction: The database "{0}" has restrictions that prevent it \
 	from being able to store the value "{1}" of type "{2}". The value \
 	will be rounded to "{3}" for storage.
@@ -135,9 +135,8 @@
 	substring function.
 null-result-provider: supplied array of result object providers is null
 empty-result-provider: supplied array of result object providers is empty
-null-shared-result-set: supplied result set is null  
-illegal-method: {0}.{1}() is illegal to be invoked 
+null-shared-result-set: supplied result set is null
+illegal-method: {0}.{1}() is illegal to be invoked
 column-not-mapped: SQLResultSetMapping "{0}" does not map the columns "{1}" \
 	that are selected by the SQL query\r\n "{2}"
-batch-license: Your license does not have SQL batching capabilities.
 dictionary-configuration: DBDictionary configuration: \n{0}

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java Mon Sep 18 14:57:52 2006
@@ -26,6 +26,7 @@
     private boolean _copyIds = false;
     private boolean _closeOnCommit = true;
     private boolean _quotedNumbers = false;
+    private boolean _nonOptimisticVersionCheck = false;
 
     /**
      * Whether to require exact identity value types when creating object
@@ -136,4 +137,24 @@
     public void setCloseOnManagedCommit(boolean close) {
         _closeOnCommit = close;
 	}	
+
+    /** 
+     * Whether or not to perform a version check on instances being updated
+     * in a datastore transaction. Version of OpenJPA prior to 4.1 always
+     * forced a version check.
+     */
+    public void setNonOptimisticVersionCheck
+        (boolean nonOptimisticVersionCheck) {
+        _nonOptimisticVersionCheck = nonOptimisticVersionCheck;
+    }
+
+    /** 
+     * Whether or not to perform a version check on instances being updated
+     * in a datastore transaction. Version of OpenJPA prior to 4.1 always
+     * forced a version check.
+     */
+    public boolean getNonOptimisticVersionCheck() {
+        return _nonOptimisticVersionCheck;
+    }
+
 }

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java Mon Sep 18 14:57:52 2006
@@ -20,8 +20,8 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
@@ -510,13 +510,17 @@
         for (Iterator itr = states.iterator(); itr.hasNext();) {
             sm = (OpenJPAStateManager) itr.next();
 
-            if (sm.getPCState() == PCState.PNEW) {
+            if (sm.getPCState() == PCState.PNEW && !sm.isFlushed()) {
                 if (_inserts == null)
-                    _inserts = new LinkedList();
+                    _inserts = new ArrayList();
                 _inserts.add(sm);
-            } else if (_inserts != null &&
-                (sm.getPCState() == PCState.PNEWDELETED ||
-                sm.getPCState() == PCState.PNEWFLUSHEDDELETED))
+
+                // may have been re-persisted
+                if (_deletes != null)
+                    _deletes.remove(sm);
+            } else if (_inserts != null 
+                && (sm.getPCState() == PCState.PNEWDELETED 
+                || sm.getPCState() == PCState.PNEWFLUSHEDDELETED))
                 _inserts.remove(sm);
             else if (sm.getPCState() == PCState.PDIRTY) {
                 if (_updates == null)
@@ -524,7 +528,7 @@
                 _updates.put(sm, sm.getDirty());
             } else if (sm.getPCState() == PCState.PDELETED) {
                 if (_deletes == null)
-                    _deletes = new LinkedList();
+                    _deletes = new HashSet();
                 _deletes.add(sm);
             }
         }
@@ -572,10 +576,10 @@
      */
     private static class Modifications {
 
-        public final List additions = new LinkedList();
-        public final List newUpdates = new LinkedList();
-        public final List existingUpdates = new LinkedList();
-        public final List deletes = new LinkedList();
+        public final List additions = new ArrayList();
+        public final List newUpdates = new ArrayList();
+        public final List existingUpdates = new ArrayList();
+        public final List deletes = new ArrayList();
     }
 
     private static class PCDataHolder {

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java Mon Sep 18 14:57:52 2006
@@ -1904,7 +1904,7 @@
                 method.makeProtected();
                 access = "protected";
             }
-            if (_log.isWarnEnabled())
+            if (!_meta.getDescribedType().isInterface() && _log.isWarnEnabled())
                 _log.warn(_loc.get("enhance-adddefaultconst", type, access));
         }
     }

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/event/BeanLifecycleCallbacks.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/event/BeanLifecycleCallbacks.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/event/BeanLifecycleCallbacks.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/event/BeanLifecycleCallbacks.java Mon Sep 18 14:57:52 2006
@@ -38,9 +38,10 @@
      *
      * @arg whether another argunent is expected such as AfterDetach
      */
-    public BeanLifecycleCallbacks(Class cls, String method, boolean arg) {
+    public BeanLifecycleCallbacks(Class cls, String method, boolean arg,
+        Class type) {
         this(cls, getMethod(cls, method, arg ? new Class[]{ Object.class,
-            Object.class } : new Class[]{ Object.class }), arg);
+            type } : new Class[]{ type }), arg);
     }
 
     /**

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/event/MethodLifecycleCallbacks.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/event/MethodLifecycleCallbacks.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/event/MethodLifecycleCallbacks.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/event/MethodLifecycleCallbacks.java Mon Sep 18 14:57:52 2006
@@ -16,6 +16,7 @@
 package org.apache.openjpa.event;
 
 import java.lang.reflect.Method;
+import java.util.Arrays;
 
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.util.UserException;
@@ -92,7 +93,17 @@
      */
     protected static Method getMethod(Class cls, String method, Class[] args) {
         try {
+            Method[] methods = cls.getMethods();
+            for (int i = 0; i < methods.length; i++) {
+                if (!method.equals(methods[i].getName()))
+                    continue;
+
+                if (isAssignable(methods[i].getParameterTypes(), args))
+                    return methods[i];
+            }
+
             return cls.getMethod(method, args);
+
         } catch (Throwable t) {
             try {
                 // try again with the declared methods, which will
@@ -103,8 +114,28 @@
                 return m;
             } catch (Throwable t2) {
                 throw new UserException(_loc.get("method-notfound",
-                    cls.getName(), method), t);
+                    cls.getName(), method,
+                        args == null ? null : Arrays.asList(args)), t);
             }
 		}
 	}
+
+    /** 
+     * Returns true if all parameters in the from array are assignable
+     * from the corresponding parameters of the to array. 
+     */
+    private static boolean isAssignable(Class[] from, Class[] to) {
+        if (from == null)
+            return to == null;
+
+        if (from.length != to.length)
+            return false;
+
+        for (int i = 0; i < from.length; i++) {
+            if (from[i] != null && !from[i].isAssignableFrom(to[i]))
+                return false;
+        }
+
+        return true;
+    } 
 }

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerFactory.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerFactory.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerFactory.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerFactory.java Mon Sep 18 14:57:52 2006
@@ -96,6 +96,6 @@
 
     /**
      * Release the internal lock.
-	 */
-	public void unlock ();
+     */
+    public void unlock ();
 }

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Mon Sep 18 14:57:52 2006
@@ -135,6 +135,7 @@
     private static final int FLAG_FLUSH_REQUIRED = 2 << 8;
     private static final int FLAG_REMOTE_LISTENER = 2 << 9;
     private static final int FLAG_RETAINED_CONN = 2 << 10;
+    private static final int FLAG_TRANS_ENDING = 2 << 11;
 
     private static final Localizer _loc =
         Localizer.forPackage(BrokerImpl.class);
@@ -1640,6 +1641,14 @@
         }
     }
 
+    /**
+     * Return whether the current transaction is ending, i.e. in the 2nd phase
+     * of a commit or rollback
+     */
+    boolean isTransactionEnding() {
+        return (_flags & FLAG_TRANS_ENDING) != 0;
+    }
+
     public boolean beginOperation(boolean syncTrans) {
         lock();
         try {
@@ -1722,6 +1731,7 @@
         try {
             assertActiveTransaction();
 
+            _flags |= FLAG_TRANS_ENDING;
             endTransaction(status);
             if (_sync != null)
                 _sync.afterCompletion(status);
@@ -1746,9 +1756,10 @@
         } finally {
             _flags &= ~FLAG_ACTIVE;
             _flags &= ~FLAG_FLUSHED;
+            _flags &= ~FLAG_TRANS_ENDING;
 
-            if (_transEventManager != null &&
-                _transEventManager.hasEndListeners()) {
+            if (_transEventManager != null 
+                && _transEventManager.hasEndListeners()) {
                 _transEventManager.fireEvent(new TransactionEvent(this,
                     status == Status.STATUS_COMMITTED
                         ? TransactionEvent.AFTER_COMMIT_COMPLETE
@@ -2404,9 +2415,9 @@
         if (sm != null) {
             if (sm.isDetached())
                 throw newDetachedException(obj, "delete");
-            sm.delete();
             if ((action & OpCallbacks.ACT_CASCADE) != 0)
                 sm.cascadeDelete(call);
+            sm.delete();
         } else if (assertPersistenceCapable(obj).pcIsDetached() == Boolean.TRUE)
             throw newDetachedException(obj, "delete");
     }
@@ -3016,10 +3027,9 @@
         StateManagerImpl sm;
         for (Iterator itr = states.iterator(); itr.hasNext();) {
             sm = (StateManagerImpl) itr.next();
-            if (!sm.isPersistent()) {
-                sm.nontransactional();
+            if (!sm.isPersistent())
                 itr.remove();
-            } else if (!sm.getMetaData().isDetachable()) {
+            else if (!sm.getMetaData().isDetachable()) {
                 sm.release(true);
                 itr.remove();
             }
@@ -4129,6 +4139,18 @@
             return null;
         if (obj instanceof PersistenceCapable)
             return (PersistenceCapable) obj;
+
+        // check for difference instances of the PersistenceCapable interface
+        // and throw a better error that mentions the class loaders
+        Class[] intfs = obj.getClass().getInterfaces();
+        for (int i = 0; intfs != null && i < intfs.length; i++) {
+            if (intfs[i].getName().equals(PersistenceCapable.class.getName())) {
+                throw new UserException(_loc.get("pc-loader-different",
+                    Exceptions.toString(obj),
+                    PersistenceCapable.class.getClassLoader(),
+                    intfs[i].getClassLoader())).setFailedObject(obj);
+            }
+        }
 
         // not enhanced
         throw new UserException(_loc.get("pc-cast",

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java Mon Sep 18 14:57:52 2006
@@ -259,20 +259,17 @@
      * Return a detached version of the given instance.
      */
     public Object detach(Object toDetach) {
-        CallbackException excep = null;
+        List exceps = null;
         try {
             return detachInternal(toDetach);
         } catch (CallbackException ce) {
-            excep = ce;
+            exceps = new ArrayList(1);
+            exceps.add(ce);
             return null; // won't be reached as exception will be rethrown
         } finally {
-            List exceps = null;
-
-            if (excep == null || !_failFast) {
+            if (exceps == null || !_failFast)
                 exceps = invokeAfterDetach(Collections.singleton(toDetach),
-                    null);
-            } else
-                exceps = Collections.singletonList(excep);
+                    exceps);
             if (_detached != null)
                 _detached.clear();
             throwExceptions(exceps);
@@ -303,11 +300,8 @@
                 failFast = true;
             exceps = add(exceps, re);
         } finally {
-            // invoke post callbacks unless all failed
-            if (!failFast && (exceps == null
-                || exceps.size() < instances.size())) {
+            if (!failFast)
                 exceps = invokeAfterDetach(instances, exceps);
-            }
             if (_detached != null)
                 _detached.clear();
         }

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECleanState.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECleanState.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECleanState.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECleanState.java Mon Sep 18 14:57:52 2006
@@ -17,7 +17,7 @@
 
 /**
  * Lifecycle state.
- *  Represents an embedded instance that is managed by a StateManager and
+ * Represents an embedded instance that is managed by a StateManager and
  * may be participating in the current	transaction, but has not yet been
  * modified.
  *

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECopyState.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECopyState.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECopyState.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECopyState.java Mon Sep 18 14:57:52 2006
@@ -17,7 +17,7 @@
 
 /**
  * Lifecycle state.
- *  Represents an instance that was copied and made embedded within the
+ * Represents an instance that was copied and made embedded within the
  * current	transaction.
  *
  * @author Abe White

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDeletedState.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDeletedState.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDeletedState.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDeletedState.java Mon Sep 18 14:57:52 2006
@@ -17,7 +17,7 @@
 
 /**
  * Lifecycle state.
- *  Represents an embedded instance that has been deleted in the current
+ * Represents an embedded instance that has been deleted in the current
  * transaction.
  *
  * @author Abe White

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDirtyState.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDirtyState.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDirtyState.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDirtyState.java Mon Sep 18 14:57:52 2006
@@ -17,7 +17,7 @@
 
 /**
  * Lifecycle state.
- *  Represents an embedded instance that is participating in the current
+ * Represents an embedded instance that is participating in the current
  * transaction, and has been modified.
  *
  * @author Abe White

Modified: incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ENonTransState.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ENonTransState.java?view=diff&rev=447584&r1=447583&r2=447584
==============================================================================
--- incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ENonTransState.java (original)
+++ incubator/openjpa/sandboxes/OPENJPA-24/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ENonTransState.java Mon Sep 18 14:57:52 2006
@@ -17,7 +17,7 @@
 
 /**
  * Lifecycle state.
- *  Represents an embedded instance that is not transactional, but that
+ * Represents an embedded instance that is not transactional, but that
  * allows access to persistent data. This state is reachable only if the
  * retainValues flag of the broker is set.
  *
@@ -55,13 +55,11 @@
     }
 
     PCState beforeRead(StateManagerImpl context, int field) {
-        error("embed-ref", context);
-        return null;
+        return error("embed-ref", context);
     }
 
     PCState beforeWrite(StateManagerImpl context, int field, boolean mutate) {
-        error("embed-ref", context);
-        return null;
+        return error("embed-ref", context);
     }
 
     PCState beforeOptimisticWrite(StateManagerImpl context, int field,