You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by mi...@apache.org on 2010/02/11 23:32:31 UTC

svn commit: r909167 - in /openjpa/branches/1.3.x: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ openjpa-persistence-jdb...

Author: mikedd
Date: Thu Feb 11 22:32:26 2010
New Revision: 909167

URL: http://svn.apache.org/viewvc?rev=909167&view=rev
Log:
OPENJPA-1001:
Prevent IndexOutOfBoundsException.
Submitted By: B.J. Reed, Richard Rak

Added:
    openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestIncompleteRelationship.java   (with props)
    openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/
    openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipChildEntity.java   (with props)
    openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipParentEntity.java   (with props)
    openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipSubclass.java   (with props)
Modified:
    openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
    openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
    openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java
    openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java
    openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java

Modified: openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?rev=909167&r1=909166&r2=909167&view=diff
==============================================================================
--- openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java (original)
+++ openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java Thu Feb 11 22:32:26 2010
@@ -499,90 +499,13 @@
     private Result getInitializeStateResult(OpenJPAStateManager sm,
         ClassMapping mapping, JDBCFetchConfiguration fetch, int subs)
         throws SQLException {
-        List params = new ArrayList();
-        Select sel = newSelect(sm, mapping, fetch, subs, params);
-        if (sel == null) return null;
-        return sel.execute(this, fetch, params);
-    }
-    
-    Map<SelectKey, Select> selectImplCacheMap = null;
-    private Select newSelect(OpenJPAStateManager sm,
-        ClassMapping mapping, JDBCFetchConfiguration fetch, int subs,
-        List params) {
-        if (!_isQuerySQLCache) 
-            return newSelect(sm, mapping, fetch, subs);       
-           
-        if (selectImplCacheMap == null) {
-            selectImplCacheMap =
-                getCacheMapFromQuerySQLCache(JDBCStoreManager.class);
-        }
-         
-        JDBCFetchConfiguration fetchClone = new JDBCFetchConfigurationImpl();
-        fetchClone.copy(fetch);
-        SelectKey selKey = new SelectKey(mapping, null, fetchClone);
-        Select sel = null;
-        boolean found = true;
-        Object obj = selectImplCacheMap.get(selKey);
-        if (obj == null) {
-            synchronized (selectImplCacheMap) {
-                obj = selectImplCacheMap.get(selKey);
-                if (obj == null) {
-                    // Not found in cache, create a new select
-                    obj = newSelect(sm, mapping, fetch, subs);
-                    found = false;
-                }
-                    
-                if (obj == null) {
-                    // If the generated SelectImpl is null, store a generic
-                    // known object in the cache as a placeholder. Some map 
-                    // implementations do not allow null values.
-                    obj = _nullCacheValue;
-                    found = false;
-                }
-                else if (obj != _nullCacheValue)
-                {
-                    sel = (Select)obj;
-                    if (sel.getSQL() == null) {
-                        sel.setSQL(this, fetch);
-                        found = false;
-                    }
-                }
-                if (!found) {
-                    addToSqlCache(selectImplCacheMap, selKey, obj);
-                }
-            }
-        }
-
-        if (obj != null && obj != _nullCacheValue)
-            sel = (Select) obj;
-
-        Log log = _conf.getLog(JDBCConfiguration.LOG_JDBC);
-        if (log.isTraceEnabled()) {
-            if (!found)
-                log.trace(_loc.get("cache-missed", mapping, this.getClass()));
-            else
-                log.trace(_loc.get("cache-hit", mapping, this.getClass()));
-        }
-
-        if (sel == null)
-            return null;
-        
-        Object oid = sm.getObjectId();
-        Column[] cols = mapping.getPrimaryKeyColumns();
-        sel.wherePrimaryKey(mapping, cols, cols, oid, this, 
-        	null, null, params);
-        return sel;
-    }
-
-    protected Select newSelect(OpenJPAStateManager sm,
-        ClassMapping mapping, JDBCFetchConfiguration fetch, int subs) {
         Select sel = _sql.newSelect();
-        if (!select(sel, mapping, subs, sm, null, fetch,
-            JDBCFetchConfiguration.EAGER_JOIN, true, false))
+        if (!select(sel, mapping, subs, sm, null, fetch, JDBCFetchConfiguration.EAGER_JOIN, true, false)) {
             return null;
+        }
         sel.wherePrimaryKey(sm.getObjectId(), mapping, this);
         sel.setExpectedResultCount(1, false);
-        return sel;
+        return sel.execute(this, fetch);
     }
 
     /**

Modified: openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java?rev=909167&r1=909166&r2=909167&view=diff
==============================================================================
--- openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java (original)
+++ openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java Thu Feb 11 22:32:26 2010
@@ -620,99 +620,6 @@
         final int subs = field.getSelectSubclasses();
         final Joins[] resJoins = new Joins[rels.length];
 
-        //cache union for field here
-        //select data for this sm
-        Union union = null;
-        SelectImpl sel = null;
-        List parmList = null;
-
-        if (!((JDBCStoreManager)store).isQuerySQLCacheOn())
-            union = newUnion(sm, store, fetch, rels, subs, resJoins);
-        else {
-            if (relationFieldUnionCache == null) {
-                relationFieldUnionCache =
-                    ((JDBCStoreManager) store)
-                        .getCacheMapFromQuerySQLCache(RelationFieldStrategy.class);
-            }
-            boolean found = true;
-            JDBCFetchConfiguration fetchClone = new JDBCFetchConfigurationImpl();
-            fetchClone.copy(fetch);
-            JDBCStoreManager.SelectKey selKey = 
-                new JDBCStoreManager.SelectKey(null, field, fetch);
-            Object[] obj = relationFieldUnionCache.get(selKey);
-            if (obj != null) {
-                union = (Union) obj[0];
-                resJoins[0] = (Joins)obj[1];
-            } else {
-                synchronized(relationFieldUnionCache) {
-                    obj = relationFieldUnionCache.get(selKey);
-                    if (obj != null) {
-                        union = (Union) obj[0];
-                        resJoins[0] = (Joins) obj[1];
-                    } else {
-                        // select related mapping columns; joining from the 
-                        // related type back to our fk table if not an inverse 
-                        // mapping (in which case we can just make sure the 
-                        // inverse cols == our pk values)
-                        union = newUnion(sm, store, fetch, rels, subs, 
-                                resJoins);
-                        found = false;                
-                    }
-                    sel = ((LogicalUnion.UnionSelect)union.getSelects()[0]).
-                        getDelegate();
-                    SQLBuffer buf = sel.getSQL();
-                    if (buf == null) {
-                    	((SelectImpl)sel).setSQL(store, fetch);
-                        found = false;
-                    }
-
-                    // only cache the union when elems length is 1 for now
-                    if (!found && rels.length == 1) {
-                        Object[] obj1 = new Object[2];
-                        obj1[0] = union;
-                        obj1[1] = resJoins[0];
-                        ((JDBCStoreManager)store).addToSqlCache(
-                            relationFieldUnionCache, selKey, obj1);
-                    }
-                }
-            }
-            Log log = store.getConfiguration().
-                getLog(JDBCConfiguration.LOG_JDBC);
-            if (log.isTraceEnabled()){
-                if (found) 
-                    log.trace(_loc.get("cache-hit", field, this.getClass()));                        
-                else
-                    log.trace(_loc.get("cache-missed", field, this.getClass()));
-            }
-
-            parmList = new ArrayList();
-            ClassMapping mapping = field.getDefiningMapping();
-            Object oid = sm.getObjectId();
-            Column[] cols = mapping.getPrimaryKeyColumns();
-            if (sel == null)
-                sel = ((LogicalUnion.UnionSelect)union.getSelects()[0]).
-                getDelegate();
-
-            sel.wherePrimaryKey(mapping, cols, cols, oid, store, 
-            	null, null, parmList);
-        }
-        
-        Result res = union.execute(store, fetch, parmList);
-        try {
-            Object val = null;
-            if (res.next())
-                val = res.load(rels[res.indexOf()], store, fetch,
-                    resJoins[res.indexOf()]);
-            sm.storeObject(field.getIndex(), val);
-        } finally {
-            res.close();
-        }
-    }
-    
-    protected Union newUnion(final OpenJPAStateManager sm, 
-        final JDBCStore store, final JDBCFetchConfiguration fetch, 
-        final ClassMapping[] rels, final int subs, 
-        final Joins[] resJoins) {
         Union union = store.getSQLFactory().newUnion(rels.length);
         union.setExpectedResultCount(1, false);
         if (fetch.getSubclassFetchMode(field.getTypeMapping())
@@ -720,20 +627,29 @@
             union.abortUnion();
         union.select(new Union.Selector() {
             public void select(Select sel, int idx) {
-                if (field.getJoinDirection() == field.JOIN_INVERSE)
-                    sel.whereForeignKey(field.getForeignKey(rels[idx]),
-                        sm.getObjectId(), field.getDefiningMapping(), store);
+                if (field.getJoinDirection() == field.JOIN_INVERSE) {
+                    sel.whereForeignKey(field.getForeignKey(rels[idx]), sm.getObjectId(), field.getDefiningMapping(),
+                        store);
+                }
                 else {
-                    resJoins[idx] = sel.newJoins().joinRelation(field.getName(),
-                        field.getForeignKey(rels[idx]), rels[idx],
-                        field.getSelectSubclasses(), false, false);
+                    resJoins[idx] =
+                        sel.newJoins().joinRelation(field.getName(), field.getForeignKey(rels[idx]), rels[idx],
+                            field.getSelectSubclasses(), false, false);
                     field.wherePrimaryKey(sel, sm, store);
                 }
-                sel.select(rels[idx], subs, store, fetch, fetch.EAGER_JOIN, 
-                    resJoins[idx]);
+                sel.select(rels[idx], subs, store, fetch, fetch.EAGER_JOIN, resJoins[idx]);
             }
         });
-        return union;
+        Result res = union.execute(store, fetch);
+        try {
+            Object val = null;
+            if (res.next()) {
+                val = res.load(rels[res.indexOf()], store, fetch, resJoins[res.indexOf()]);
+            }
+            sm.storeObject(field.getIndex(), val);
+        } finally {
+            res.close();
+        }
     }
 
     public Object toDataStoreValue(Object val, JDBCStore store) {

Modified: openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java?rev=909167&r1=909166&r2=909167&view=diff
==============================================================================
--- openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java (original)
+++ openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java Thu Feb 11 22:32:26 2010
@@ -59,7 +59,7 @@
     protected final BitSet desc = new BitSet();
     private boolean _distinct = true;
    
-
+ 
     /**
      * Constructor.
      *
@@ -194,6 +194,15 @@
                 return false;
         return true;
     }
+    
+    public boolean hasMultipleSelects() {
+        for (UnionSelect sel : sels) {
+            if (sel.hasMultipleSelects()) {
+                return true;
+            }
+        }
+        return false;
+    }
 
     public int getCount(JDBCStore store)
         throws SQLException {
@@ -204,32 +213,21 @@
     }
 
     public Result execute(JDBCStore store, JDBCFetchConfiguration fetch)
-            throws SQLException {
-        return execute(store, fetch, null);
-    }    
-
-    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
-        int lockLevel)
         throws SQLException {
-        return execute(store, fetch, lockLevel, null);
-    }
-    
-    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch, 
-        List params)
-        throws SQLException {
-        if (fetch == null)
+        if (fetch == null) {
             fetch = store.getFetchConfiguration();
-        return execute(store, fetch, fetch.getReadLockLevel(), params);
+        }
+        return execute(store, fetch, fetch.getReadLockLevel());
     }
 
     public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
-        int lockLevel, List params)
+        int lockLevel)
         throws SQLException {
         if (fetch == null)
             fetch = store.getFetchConfiguration();
 
         if (sels.length == 1) {
-            Result res = sels[0].execute(store, fetch, lockLevel, params);
+            Result res = sels[0].execute(store, fetch, lockLevel);
             ((AbstractResult) res).setBaseMapping(mappings[0]);
             return res;
         }
@@ -238,7 +236,7 @@
             AbstractResult res;
             for (int i = 0; i < sels.length; i++) {
                 res = (AbstractResult) sels[i].execute(store, fetch,
-                    lockLevel, params);
+                    lockLevel);
                 res.setBaseMapping(mappings[i]);
                 res.setIndexOf(i);
 
@@ -270,7 +268,7 @@
             List l;
             for (int i = 0; i < res.length; i++) {
                 res[i] = (AbstractResult) sels[i].execute(store, fetch,
-                    lockLevel, params);
+                    lockLevel);
                 res[i].setBaseMapping(mappings[i]);
                 res[i].setIndexOf(i);
 
@@ -404,24 +402,16 @@
         public boolean supportsLocking() {
             return sel.supportsLocking();
         }
+        
+        public boolean hasMultipleSelects() {
+            return sel.hasMultipleSelects();
+        }
 
         public int getCount(JDBCStore store)
             throws SQLException {
             return sel.getCount(store);
         }
 
-        public Result execute(JDBCStore store, JDBCFetchConfiguration fetch, 
-            List params)
-            throws SQLException {
-            return sel.execute(store, fetch, params);
-        }
-
-        public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
-            int lockLevel, List params)
-            throws SQLException {
-            return sel.execute(store, fetch, lockLevel, params);
-        }
-
         public Result execute(JDBCStore store, JDBCFetchConfiguration fetch)
             throws SQLException {
             return sel.execute(store, fetch);
@@ -911,6 +901,15 @@
         public void setSchemaAlias(String schemaAlias) {
             sel.setSchemaAlias(schemaAlias);
         }
+
+        public Result execute(JDBCStore store, JDBCFetchConfiguration fetch, List params) throws SQLException {
+            return execute(store, fetch);
+        }
+
+        public Result execute(JDBCStore store, JDBCFetchConfiguration fetch, int lockLevel, List params)
+            throws SQLException {
+            return execute(store, fetch, lockLevel);
+        }
     }
 
     /**
@@ -991,4 +990,13 @@
             return a1.length - a2.length;
         }
     }
+
+    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch, List params) throws SQLException {
+        return execute(store, fetch);
+    }
+
+    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch, int lockLevel, List params)
+        throws SQLException {
+        return execute(store, fetch, lockLevel);
+    }
 }

Modified: openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java?rev=909167&r1=909166&r2=909167&view=diff
==============================================================================
--- openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java (original)
+++ openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java Thu Feb 11 22:32:26 2010
@@ -132,6 +132,7 @@
 
     /**
      * Execute this select in the context of the given store manager.
+     * @deprecated
      */
     public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
         List params) 
@@ -139,6 +140,7 @@
 
     /**
      * Execute this select in the context of the given store manager.
+     * @deprecated
      */
     public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
         int lockLevel, List params)
@@ -148,6 +150,13 @@
      * Execute this select in the context of the given store manager.
      */
     public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
-        int lockLevel)
+        int lockLevel) 
         throws SQLException;
+
+    /**
+     * Execute this select in the context of the given store manager.
+     * Affirm if this receiver requires more than one selects to fetch its
+     * data. 
+     */
+    public boolean hasMultipleSelects();
 }

Modified: openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=909167&r1=909166&r2=909167&view=diff
==============================================================================
--- openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java (original)
+++ openjpa/branches/1.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java Thu Feb 11 22:32:26 2010
@@ -305,6 +305,20 @@
     public boolean supportsLocking() {
         return _dict.supportsLocking(this);
     }
+    
+    public boolean hasMultipleSelects() {
+        if (_eager == null) {
+            return false;
+        }
+        Map.Entry entry;
+        for (Iterator itr = _eager.entrySet().iterator(); itr.hasNext();) {
+            entry = (Map.Entry) itr.next();
+            if (entry.getValue() != this) {
+                return true;
+            }
+        }
+        return false;
+    }
 
     public int getCount(JDBCStore store)
         throws SQLException {
@@ -317,7 +331,7 @@
             stmnt = prepareStatement(conn, sql, null, 
                 ResultSet.TYPE_FORWARD_ONLY, 
                 ResultSet.CONCUR_READ_ONLY, false);
-            rs = executeQuery(conn, stmnt, sql, false, store, null);
+            rs = executeQuery(conn, stmnt, sql, false, store);
             return getCount(rs);
         } finally {
             if (rs != null)
@@ -329,31 +343,21 @@
         }
     }
 
-    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch, 
-        List parms) throws SQLException {
+    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch)
+        throws SQLException {
         if (fetch == null)
             fetch = store.getFetchConfiguration();
         return execute(store.getContext(), store, fetch,
-            fetch.getReadLockLevel(), parms);
-    }
-
-    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch) 
-        throws SQLException {
-        return execute(store, fetch, null);
-     }
-
-    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
-        int lockLevel, List parms)
-        throws SQLException {
-            if (fetch == null)
-                fetch = store.getFetchConfiguration();
-            return execute(store.getContext(), store, fetch, lockLevel, parms);
+            fetch.getReadLockLevel());
     }
 
     public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
         int lockLevel)
         throws SQLException {
-        return execute(store, fetch, lockLevel, null);
+        if (fetch == null) {
+            fetch = store.getFetchConfiguration();
+        }
+        return execute(store.getContext(), store, fetch, lockLevel);
     }
 
     /**
@@ -361,7 +365,7 @@
      * context is passed in separately for profiling purposes.
      */
     protected Result execute(StoreContext ctx, JDBCStore store, 
-        JDBCFetchConfiguration fetch, int lockLevel, List params)
+        JDBCFetchConfiguration fetch, int lockLevel)
         throws SQLException {
         boolean forUpdate = isForUpdate(store, lockLevel);
         
@@ -384,15 +388,13 @@
         ResultSet rs = null;
         try {
             if (isLRS) 
-                stmnt = prepareStatement(conn, _sql, fetch, rsType, -1, true, 
-                        params); 
+                stmnt = prepareStatement(conn, _sql, fetch, rsType, -1, true); 
             else
-                stmnt = prepareStatement(conn, _sql, null, rsType, -1, false, 
-                        params);
+                stmnt = prepareStatement(conn, _sql, null, rsType, -1, false);
             
             setTimeout(stmnt, forUpdate, fetch);
             
-            rs = executeQuery(conn, stmnt, _sql, isLRS, store, params);
+            rs = executeQuery(conn, stmnt, _sql, isLRS, store);
         } catch (SQLException se) {
             // clean up statement
             if (stmnt != null)
@@ -401,8 +403,7 @@
             throw se;
         }
 
-        return getEagerResult(conn, stmnt, rs, store, fetch, forUpdate, 
-            _sql.getSQL(), params);
+        return getEagerResult(conn, stmnt, rs, store, fetch, forUpdate, _sql);
     }
     
     private boolean isForUpdate(JDBCStore store, int lockLevel) {
@@ -420,7 +421,7 @@
      * to the given result.
      */
     private static void addEagerResults(SelectResult res, SelectImpl sel,
-        JDBCStore store, JDBCFetchConfiguration fetch, List params)
+        JDBCStore store, JDBCFetchConfiguration fetch)
         throws SQLException {
         if (sel._eager == null)
             return;
@@ -439,7 +440,7 @@
                 eres = res;
             else
                 eres = ((SelectExecutor) entry.getValue()).execute(store,
-                    fetch, params);
+                    fetch);
 
             eager = res.getEagerMap(false);
             if (eager == null) {
@@ -450,17 +451,10 @@
         }
     }
 
-
-    /**
-     * 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 {
-        // add comments why we pass in null as the last parameter
-        return prepareStatement(conn, sql, fetch, rsType, rsConcur, isLRS, 
-                null);
+        int rsConcur, boolean isLRS, List params) throws SQLException {
+        return prepareStatement(conn, sql, fetch, rsType, rsConcur, isLRS);
     }
 
     /**
@@ -469,11 +463,11 @@
      */
     protected PreparedStatement prepareStatement(Connection conn, 
         SQLBuffer sql, JDBCFetchConfiguration fetch, int rsType, 
-        int rsConcur, boolean isLRS, List params) throws SQLException {
+        int rsConcur, boolean isLRS) throws SQLException {
         if (fetch == null)
-            return sql.prepareStatement(conn, rsType, rsConcur, params);
+            return sql.prepareStatement(conn, rsType, rsConcur);
         else
-            return sql.prepareStatement(conn, fetch, rsType, -1, params);
+            return sql.prepareStatement(conn, fetch, rsType, -1);
     }
     
     /**
@@ -515,7 +509,7 @@
      * implementation of executing query.
      */
     protected ResultSet executeQuery(Connection conn, PreparedStatement stmnt, 
-        SQLBuffer sql, boolean isLRS, JDBCStore store, List params) 
+        SQLBuffer sql, boolean isLRS, JDBCStore store) 
         throws SQLException {
         return stmnt.executeQuery();
     }
@@ -535,15 +529,14 @@
      */
     protected Result getEagerResult(Connection conn, 
         PreparedStatement stmnt, ResultSet rs, JDBCStore store, 
-        JDBCFetchConfiguration fetch, boolean forUpdate, String sqlStr,
-        List params) 
+        JDBCFetchConfiguration fetch, boolean forUpdate, SQLBuffer sql) 
         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, params);
+            addEagerResults(res, this, store, fetch);
         } catch (SQLException se) {
             res.close();
             throw se;
@@ -1414,10 +1407,11 @@
                 val = pks[mapping.getField(join.getFieldIndex()).
                     getPrimaryKeyIndex()];
                 val = join.getJoinValue(val, toCols[i], store);
-                if (parmList != null)
+                
+                if (parmList != null) {
                 	parmList.add(val);
+                }
             }
-            
             if (collectParmValueOnly) 
             	continue;
             
@@ -3233,6 +3227,15 @@
 
     public void moveJoinsToParent() {
     }
+
+    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch, List params) throws SQLException {
+        return execute(store, fetch); 
+    }
+
+    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch, int lockLevel, List params)
+        throws SQLException {
+        return execute(store, fetch, lockLevel);
+    }
 }
 
 /**

Added: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestIncompleteRelationship.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestIncompleteRelationship.java?rev=909167&view=auto
==============================================================================
--- openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestIncompleteRelationship.java (added)
+++ openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestIncompleteRelationship.java Thu Feb 11 22:32:26 2010
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.relations;
+
+import org.apache.openjpa.persistence.relations.entity.IncompleteRelationshipChildEntity;
+import org.apache.openjpa.persistence.relations.entity.IncompleteRelationshipParentEntity;
+import org.apache.openjpa.persistence.relations.entity.IncompleteRelationshipSubclass;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+import javax.persistence.EntityManager;
+
+/**
+ * A test case that tests for incomplete foreign-key relationships and ensures
+ * that proper database mechanics are enforced.
+ */
+public class TestIncompleteRelationship extends SingleEMFTestCase {
+    private static final String CLIENT_ID = "00000-00000-00000-00000-00000-00000";
+
+    private static final String DISCOUNTS[] = {
+        "Five-Finger Discount",
+        "Staff Discount"
+    };
+
+    @Override
+    public void setUp() {
+        super.setUp(CLEAR_TABLES,
+                    IncompleteRelationshipParentEntity.class,
+                    IncompleteRelationshipParentEntity.IncompleteRelationshipParentEntityPk.class,
+                    IncompleteRelationshipChildEntity.class,
+                    IncompleteRelationshipChildEntity.IncompleteRelationshipChildEntityPk.class,
+                    IncompleteRelationshipSubclass.class,
+                    "openjpa.jdbc.QuerySQLCache", "true");
+    }
+
+    public void testIncompleteRelationship() {
+        final EntityManager em = emf.createEntityManager();
+        IncompleteRelationshipSubclass parent = null;
+        IncompleteRelationshipChildEntity child = null;
+
+        em.getTransaction().begin();
+        for (String s : DISCOUNTS) {
+            child = new IncompleteRelationshipChildEntity(s, CLIENT_ID);
+            em.persist(child);
+        }
+        em.getTransaction().commit();
+
+        for (int i = 1; i < 100; i++) {
+            em.getTransaction().begin();
+
+            parent = new IncompleteRelationshipSubclass(i, CLIENT_ID);
+//            parent.setChild(child);
+
+            em.persist(parent);
+            em.getTransaction().commit();
+
+            parent = (IncompleteRelationshipSubclass)
+                    em.createQuery("SELECT i "+
+                                   "FROM IncompleteRelationshipSubclass i "+
+                                   "WHERE   i.pk.id = :id "+
+                                   "AND     i.pk.clientId = :clientId ")
+              .setParameter("id", i)
+              .setParameter("clientId", CLIENT_ID)
+              .getSingleResult();
+
+            assertEquals(parent.getPk().getId(), i);
+            assertNull(parent.getChild());
+        }
+    }
+}

Propchange: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestIncompleteRelationship.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipChildEntity.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipChildEntity.java?rev=909167&view=auto
==============================================================================
--- openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipChildEntity.java (added)
+++ openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipChildEntity.java Thu Feb 11 22:32:26 2010
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.relations.entity;
+
+import java.io.Serializable;
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+
+/**
+ * This is the child entity for the IncompleteRelationship test case.
+ */
+@Entity
+public class IncompleteRelationshipChildEntity implements Serializable {
+    private static final long serialVersionUID = 1L;
+    
+    @Embeddable
+    public static class IncompleteRelationshipChildEntityPk implements Serializable {
+        private static final long serialVersionUID = 1L;
+        
+        @Column(name = "DISCOUNT", nullable = false, length = 120)
+        protected String discount;
+        @Column(name = "CLIENT_ID", nullable = false, length = 35)
+        protected String clientId;
+
+        public IncompleteRelationshipChildEntityPk() {
+        }
+
+        public IncompleteRelationshipChildEntityPk(String discount, String clientId) {
+            this.discount = discount;
+            this.clientId = clientId;
+        }
+
+        public String getClientId() {
+            return clientId;
+        }
+
+        public void setClientId(String clientId) {
+            this.clientId = clientId;
+        }
+
+        public String getDiscount() {
+            return discount;
+        }
+
+        public void setDiscount(String discount) {
+            this.discount = discount;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            final IncompleteRelationshipChildEntityPk other = (IncompleteRelationshipChildEntityPk) obj;
+            if ((this.discount == null) ? (other.discount != null) : !this.discount.equals(other.discount)) {
+                return false;
+            }
+            if ((this.clientId == null) ? (other.clientId != null) : !this.clientId.equals(other.clientId)) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 5;
+            hash = 53 * hash + (this.discount != null ? this.discount.hashCode() : 0);
+            hash = 53 * hash + (this.clientId != null ? this.clientId.hashCode() : 0);
+            return hash;
+        }
+
+        @Override
+        public String toString() {
+            return "IncompleteRelationshipChildEntityPk[discount="+discount+","+
+                    "clientId="+clientId+"]";
+        }
+    }
+
+    @EmbeddedId
+    protected IncompleteRelationshipChildEntityPk pk;
+
+    public IncompleteRelationshipChildEntity() {
+    }
+
+    public IncompleteRelationshipChildEntity(IncompleteRelationshipChildEntityPk pk) {
+        this.pk = pk;
+    }
+
+    public IncompleteRelationshipChildEntity(String discount, String clientId) {
+        this(new IncompleteRelationshipChildEntityPk(discount, clientId));
+    }
+
+    public IncompleteRelationshipChildEntityPk getPk() {
+        return pk;
+    }
+
+    public void setPk(IncompleteRelationshipChildEntityPk pk) {
+        this.pk = pk;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final IncompleteRelationshipChildEntity other = (IncompleteRelationshipChildEntity) obj;
+        if (this.pk != other.pk && (this.pk == null || !this.pk.equals(other.pk))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        if (this.pk != null) {
+            return pk.hashCode();
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (this.pk != null) {
+            return pk.toString();
+        } else {
+            return "IncompleteRelationshipChildEntity[pk=null]";
+        }
+    }
+}

Propchange: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipChildEntity.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipParentEntity.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipParentEntity.java?rev=909167&view=auto
==============================================================================
--- openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipParentEntity.java (added)
+++ openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipParentEntity.java Thu Feb 11 22:32:26 2010
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.relations.entity;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.ManyToOne;
+
+/**
+ * This is the parent entity for the IncompleteRelationship test case.
+ */
+@Entity
+@Inheritance(strategy = InheritanceType.JOINED)
+public class IncompleteRelationshipParentEntity implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @Embeddable
+    public static class IncompleteRelationshipParentEntityPk implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        @Column(name = "ID", nullable = false, precision = 9)
+        protected int id;
+        @Column(name = "CLIENT_ID", nullable = false, length = 35)
+        protected String clientId;
+
+        public IncompleteRelationshipParentEntityPk() {
+        }
+
+        public IncompleteRelationshipParentEntityPk(int id, String clientId) {
+            this.id = id;
+            this.clientId = clientId;
+        }
+
+        public String getClientId() {
+            return clientId;
+        }
+
+        public void setClientId(String clientId) {
+            this.clientId = clientId;
+        }
+
+        public void setId(int id) {
+            this.id = id;
+        }
+
+        public int getId() {
+            return id;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            final IncompleteRelationshipParentEntityPk other = (IncompleteRelationshipParentEntityPk) obj;
+            if (this.id != other.id) {
+                return false;
+            }
+            if ((this.clientId == null) ? (other.clientId != null) : !this.clientId.equals(other.clientId)) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 7;
+            hash = 89 * hash + (this.id);
+            hash = 89 * hash + (this.clientId != null ? this.clientId.hashCode() : 0);
+            return hash;
+        }
+
+        @Override
+        public String toString() {
+            return "IncompleteRelationshipParentEntityPk[id="+id+","+
+                    "clientId="+clientId+"]";
+        }
+    }
+
+    @EmbeddedId
+    protected IncompleteRelationshipParentEntityPk pk;
+    @JoinColumns({
+        @JoinColumn(name = "DEFAULT_DISCOUNT", referencedColumnName = "DISCOUNT"),
+        @JoinColumn(name = "CLIENT_ID", referencedColumnName = "CLIENT_ID")
+    })
+    @ManyToOne(fetch = FetchType.LAZY)
+    protected IncompleteRelationshipChildEntity child;
+
+    public IncompleteRelationshipParentEntity() {
+    }
+
+    public IncompleteRelationshipParentEntity(IncompleteRelationshipParentEntityPk pk) {
+        this.pk = pk;
+    }
+
+    public IncompleteRelationshipParentEntity(int id, String clientId) {
+        this(new IncompleteRelationshipParentEntityPk(id, clientId));
+    }
+
+    public IncompleteRelationshipChildEntity getChild() {
+        return child;
+    }
+
+    public void setChild(IncompleteRelationshipChildEntity child) {
+        this.child = child;
+    }
+
+    public IncompleteRelationshipParentEntityPk getPk() {
+        return pk;
+    }
+
+    public void setPk(IncompleteRelationshipParentEntityPk pk) {
+        this.pk = pk;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final IncompleteRelationshipParentEntity other = (IncompleteRelationshipParentEntity) obj;
+        if (this.pk != other.pk && (this.pk == null || !this.pk.equals(other.pk))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        if (this.pk != null) {
+            return pk.hashCode();
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (this.pk != null) {
+            return pk.toString();
+        } else {
+            return "IncompleteRelationshipParentEntity[pk=null]";
+        }
+    }
+}

Propchange: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipParentEntity.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipSubclass.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipSubclass.java?rev=909167&view=auto
==============================================================================
--- openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipSubclass.java (added)
+++ openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipSubclass.java Thu Feb 11 22:32:26 2010
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.relations.entity;
+
+import javax.persistence.Entity;
+
+/**
+ * This class simply extends IncompleteRelationshipParentEntity.
+ */
+@Entity
+public class IncompleteRelationshipSubclass
+        extends IncompleteRelationshipParentEntity {
+    private static final long serialVersionUID = 1L;
+
+    public IncompleteRelationshipSubclass(int id, String clientId) {
+        super(id, clientId);
+    }
+
+    public IncompleteRelationshipSubclass(IncompleteRelationshipParentEntityPk pk) {
+        super(pk);
+    }
+
+    public IncompleteRelationshipSubclass() {
+    }
+}

Propchange: openjpa/branches/1.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/entity/IncompleteRelationshipSubclass.java
------------------------------------------------------------------------------
    svn:eol-style = native