You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2009/01/30 02:27:37 UTC

svn commit: r739123 [1/3] - in /openjpa/trunk: 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/jdbc/kernel/exps/ openjpa-jdbc/src/main/jav...

Author: ppoddar
Date: Fri Jan 30 01:27:35 2009
New Revision: 739123

URL: http://svn.apache.org/viewvc?rev=739123&view=rev
Log:
OPENJPA-703: Prepared Query Cache

Added:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryCacheImpl.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQuery.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PreparedQueryCache.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryStatistics.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Address.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Author.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Book.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/CD.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Company.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Department.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Employee.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Merchandise.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Person.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/Singer.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestEagerQueries.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestParameterProcessing.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestPreparedQueryCache.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/sqlcache/TestPreparedQueryCacheExclusion.java
Removed:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/QuerySQLCacheValue.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestQuerySQLCache.java
Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfiguration.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/CollectionParam.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
    openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties
    openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Broker.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingResultList.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryLanguages.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/CollectionParam.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Param.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Parameter.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
    openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties
    openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/AbstractResultList.java
    openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/rop/ResultList.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestQueryParameterBinding.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestEntityTypeExpression.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManagerSPI.java
    openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java
    openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfiguration.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfiguration.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfiguration.java Fri Jan 30 01:27:35 2009
@@ -18,8 +18,6 @@
  */
 package org.apache.openjpa.jdbc.conf;
 
-import java.util.Map;
-
 import javax.sql.DataSource;
 
 import org.apache.openjpa.conf.OpenJPAConfiguration;
@@ -604,23 +602,4 @@
      * @see #getDataSource
      */
     public DataSource getDataSource2(StoreContext ctx);
-    
-    /**
-     * Return QuerySQLCacheValue.
-     * @since 1.2.0
-     */
-    public QuerySQLCacheValue getQuerySQLCache();
-        
-    /**
-     * Whether querySQLCache is enabled or not.
-     * @since 1.2.0
-     */
-    public boolean isQuerySQLCacheOn();
-    
-    /**
-     * Return QuerySQLCacheInstance.
-     * @since 1.2.0
-     */
-    public Map getQuerySQLCacheInstance();     
-    
 }

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java Fri Jan 30 01:27:35 2009
@@ -20,9 +20,6 @@
 
 import java.sql.Connection;
 import java.sql.ResultSet;
-import java.util.HashMap;
-import java.util.Map;
-
 import javax.sql.DataSource;
 
 import org.apache.commons.lang.StringUtils;
@@ -85,8 +82,6 @@
     public ObjectValue mappingDefaultsPlugin;
     public PluginValue driverDataSourcePlugin;
     public MappingFactoryValue mappingFactoryPlugin;
-    public QuerySQLCacheValue querySQLCache;
-    private Map querySQLCacheInstance = new HashMap(); 
 
     // used internally
     private String firstUser = null;
@@ -306,9 +301,22 @@
         seqPlugin.setAliases(JDBCSeqValue.ALIASES);
         seqPlugin.setDefault(JDBCSeqValue.ALIASES[0]);
         seqPlugin.setString(JDBCSeqValue.ALIASES[0]);
+        
+        // This plug-in is declared in superclass but defined here
+        // because PreparedQueryCache is currently available for JDBC
+        // backend only
+        preparedQueryCachePlugin = addPlugin("QuerySQLCache", true);
+        aliases = new String[] {
+            "true", "org.apache.openjpa.jdbc.kernel.PreparedQueryCacheImpl",
+            "false", null
+        };
+        preparedQueryCachePlugin.setAliases(aliases);
+        preparedQueryCachePlugin.setAliasListComprehensive(true);
+        preparedQueryCachePlugin.setDefault(aliases[0]);
+        preparedQueryCachePlugin.setClassName(aliases[1]);
+        preparedQueryCachePlugin.setDynamic(true);
+        preparedQueryCachePlugin.setInstantiatingGetter("getQuerySQLCacheInstance");
 
-        querySQLCache = new QuerySQLCacheValue("jdbc.QuerySQLCache");
-        addValue(querySQLCache);
 
         // this static initializer is to get past a weird
         // ClassCircularityError that happens only under IBM's
@@ -864,21 +872,4 @@
                 return true; 
         return false;
     }
-    
-    public void setQuerySQLCache(String querySQLCache) {
-        this.querySQLCache.setString(querySQLCache);
-    }
-
-    public QuerySQLCacheValue getQuerySQLCache() {
-        return querySQLCache;
-    }
-    
-    public boolean isQuerySQLCacheOn() {
-        return querySQLCache.isSQLCacheOn();
-    }
-
-    public Map getQuerySQLCacheInstance() {
-        return querySQLCacheInstance;
-    }
-    
 }

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java Fri Jan 30 01:27:35 2009
@@ -29,21 +29,16 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
 import java.util.Set;
-
 import javax.sql.DataSource;
 
 import org.apache.openjpa.enhance.PersistenceCapable;
 import org.apache.openjpa.event.OrphanedKeyAction;
 import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
-import org.apache.openjpa.jdbc.conf.QuerySQLCacheValue;
 import org.apache.openjpa.jdbc.meta.ClassMapping;
 import org.apache.openjpa.jdbc.meta.Discriminator;
 import org.apache.openjpa.jdbc.meta.FieldMapping;
 import org.apache.openjpa.jdbc.meta.ValueMapping;
-import org.apache.openjpa.jdbc.schema.Column;
 import org.apache.openjpa.jdbc.sql.DBDictionary;
 import org.apache.openjpa.jdbc.sql.JoinSyntaxes;
 import org.apache.openjpa.jdbc.sql.Joins;
@@ -66,12 +61,10 @@
 import org.apache.openjpa.lib.jdbc.DelegatingConnection;
 import org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement;
 import org.apache.openjpa.lib.jdbc.DelegatingStatement;
-import org.apache.openjpa.lib.log.Log;
 import org.apache.openjpa.lib.rop.MergedResultObjectProvider;
 import org.apache.openjpa.lib.rop.ResultObjectProvider;
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FetchGroup;
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.JavaTypes;
 import org.apache.openjpa.meta.ValueStrategies;
@@ -107,11 +100,7 @@
 
     // track the pending statements so we can cancel them
     private Set _stmnts = Collections.synchronizedSet(new HashSet());
-    
-    private Map _sqlCache = null;
-    private boolean _isQuerySQLCache = true;
-    private static final Object _nullCacheValue = new Object();
-    
+
     public StoreContext getContext() {
         return _ctx;
     }
@@ -137,9 +126,6 @@
 
         if (_conf.getUpdateManagerInstance().orderDirty())
             ctx.setOrderDirtyObjects(true);
-        
-        _sqlCache = _conf.getQuerySQLCacheInstance();
-        _isQuerySQLCache = _conf.isQuerySQLCacheOn();
     }
 
     public JDBCConfiguration getConfiguration() {
@@ -493,86 +479,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);
-    }
-
-    private Select newSelect(OpenJPAStateManager sm,
-        ClassMapping mapping, JDBCFetchConfiguration fetch, int subs,
-        List params) {
-        if (!_isQuerySQLCache) 
-            return newSelect(sm, mapping, fetch, subs);       
-           
-        Map<SelectKey, Select> 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))
             return null;
         sel.wherePrimaryKey(sm.getObjectId(), mapping, this);
         sel.setExpectedResultCount(1, false);
-        return sel;
+        return sel.execute(this, fetch);
     }
 
     /**
@@ -881,7 +794,8 @@
         ExpressionParser ep = QueryLanguages.parserForLanguage(language);
         if (ep != null)
             return new JDBCStoreQuery(this, ep);
-        if (QueryLanguages.LANG_SQL.equals(language))
+        if (QueryLanguages.LANG_SQL.equals(language)
+         || QueryLanguages.LANG_PREPARED_SQL.equals(language))
             return new SQLStoreQuery(this);
         return null;
     }
@@ -1603,163 +1517,4 @@
             }
         }
     }
-    
-    public Map getCacheMapFromQuerySQLCache(Object key) {
-        synchronized(_sqlCache) {
-            //sqlCache is a map of map
-            Map cacheMap = (Map)_sqlCache.get(key);
-            if (cacheMap == null) {
-                cacheMap = createSQLCache();
-                _sqlCache.put(key, cacheMap);
-            }
-            return cacheMap;
-        }
-    }
-    
-    public void addToSqlCache(Map cacheMap, Object key, Object value) {
-        cacheMap.put(key, value);
-    }
-    
-    public Map createSQLCache() {
-        QuerySQLCacheValue querySQLCache = _conf.getQuerySQLCache();
-        return (Map)querySQLCache.newInstance();
-    }
-
-    public boolean isQuerySQLCacheOn() {
-        return _isQuerySQLCache;  
-    }
-    
-    public Map getQuerySQLCache() {
-        return _sqlCache;
-    }
-    
-    public static class SelectKey {
-        public ClassMapping mapping;
-        public FieldMapping fm;
-        public JDBCFetchConfiguration fetch;
-        
-        public SelectKey (ClassMapping mapping, FieldMapping fm, 
-            JDBCFetchConfiguration fetch) {
-            this.mapping = mapping;
-            this.fm = fm;
-            this.fetch = fetch;
-        }
-        
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            SelectKey selectKey = (SelectKey) o;
-            if (fetch != null ? !equals(fetch, selectKey.fetch) :
-                selectKey.fetch != null) return false;
-            if (mapping != null ? !mapping.equals(selectKey.mapping) :
-                selectKey.mapping != null) return false;
-            if (fm != null ? !fm.equals(selectKey.fm) :
-                selectKey.fm != null) return false;
-            return true;
-        }
-        
-        public boolean equals(JDBCFetchConfiguration fetch1,
-        	JDBCFetchConfiguration fetch2) {
-            if (fetch1 == fetch2) 
-            	return true;
-
-            if (fetch1.getIsolation() != fetch2.getIsolation()) 
-            	return false;
-            if (fetch1.getFetchDirection() != fetch2.getFetchDirection()) 
-            	return false;
-            if (fetch1.getEagerFetchMode() != fetch2.getEagerFetchMode()) 
-            	return false;
-            if (fetch1.getSubclassFetchMode() != fetch2.getSubclassFetchMode()) 
-            	return false;
-            if (fetch1.getJoinSyntax() != fetch2.getJoinSyntax()) 
-            	return false;
-            Set joins1 = fetch1.getJoins();
-            Set joins2 = fetch2.getJoins();
-            if (joins1 != null ? !joins1.equals(joins2) : joins2 != null)
-                return false;
-            
-            if (fetch1.getMaxFetchDepth() != fetch2.getMaxFetchDepth()) 
-            	return false;
-            if (fetch1.getReadLockLevel() != fetch2.getReadLockLevel()) 
-            	return false;
-            if (fetch1.getWriteLockLevel() != fetch2.getWriteLockLevel()) 
-            	return false;
-            
-            boolean sameFetchGroup = false;
-            boolean hasFetchGroupAll = ((JDBCFetchConfigurationImpl)fetch1).
-            	hasFetchGroupAll();
-            boolean hasFetchGroupAll1 = ((JDBCFetchConfigurationImpl)fetch2).
-            	hasFetchGroupAll();
-            if (hasFetchGroupAll && hasFetchGroupAll1) 
-                sameFetchGroup = true;
-            else if (!hasFetchGroupAll && !hasFetchGroupAll1){
-                boolean hasFetchGroupDefault = 
-                	((JDBCFetchConfigurationImpl)fetch1).hasFetchGroupDefault();
-                boolean hasFetchGroupDefault1 = 
-                	((JDBCFetchConfigurationImpl)fetch2).hasFetchGroupDefault();
-                if (hasFetchGroupDefault && hasFetchGroupDefault1) 
-                    sameFetchGroup = true;
-            }
-            
-            if (!sameFetchGroup) {
-                Set fetchGroups = fetch1.getFetchGroups();
-                Set fetchGroups1 = fetch2.getFetchGroups();
-                if (fetchGroups != null ? !fetchGroups.equals(fetchGroups1) : 
-                	fetchGroups1 != null)
-                    return false;
-            }
-            
-            Set fields = fetch1.getFields();
-            Set fields1 = fetch2.getFields();
-            int size = fields.size();
-            int size1 = fields1.size();
-            if (size == 0 && size1 == 0)
-                return true;
-            else if (size != size1) 
-                return false;   
-            
-            if (fields != null ? !fields.equals(fields1) : fields1 != null)
-                return false;
-            
-            return true;
-        }
-        
-        
-        public int hashCode() {
-            int result = 0;
-            result = 31 * result + (mapping != null ? mapping.hashCode() : 0);
-            result = 31 * result + (fm != null ? fm.hashCode() : 0);
-            result = 31 * result + fetch.getIsolation();
-            result = 31 * result + fetch.getFetchDirection();
-            result = 31 * result + fetch.getEagerFetchMode();
-            result = 31 * result + fetch.getSubclassFetchMode();
-            result = 31 * result + fetch.getJoinSyntax();
-            Set joins = fetch.getJoins();
-            result = 31 * result + (joins != null ? joins.hashCode() : 0);
-            
-            result = 31 * result + fetch.getMaxFetchDepth();
-            result = 31 * result + fetch.getReadLockLevel();
-            result = 31 * result + fetch.getWriteLockLevel();
-        	
-            if (((JDBCFetchConfigurationImpl)fetch).hasFetchGroupAll()) 
-            	result = 31 * result + FetchGroup.NAME_ALL.hashCode();
-            else {
-                Set fetchGroups = fetch.getFetchGroups();
-                if (((JDBCFetchConfigurationImpl)fetch).hasFetchGroupDefault() 
-                	&& fetchGroups != null && fetchGroups.size() == 1)
-                    result = 31 * result + FetchGroup.NAME_DEFAULT.hashCode();
-                else {
-                    result = 31 * result + (fetchGroups != null && 
-                        fetchGroups.size() > 0 ? 
-                        fetchGroups.hashCode() : 0);
-                }
-            }
-            Set fields = fetch.getFields();
-        	result = 31 * result + (fields != null &&  fields.size() > 0 ? 
-        		fields.hashCode() : 0);
-            
-            return result;
-        }
-    }
 }

Added: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryCacheImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryCacheImpl.java?rev=739123&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryCacheImpl.java (added)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryCacheImpl.java Fri Jan 30 01:27:35 2009
@@ -0,0 +1,368 @@
+/*
+ * 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.jdbc.kernel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.SelectExecutor;
+import org.apache.openjpa.kernel.FetchConfiguration;
+import org.apache.openjpa.kernel.PreparedQuery;
+import org.apache.openjpa.kernel.PreparedQueryCache;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.kernel.QueryHints;
+import org.apache.openjpa.kernel.QueryStatistics;
+import org.apache.openjpa.kernel.QueryStatistics.Default;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.log.LogFactory;
+import org.apache.openjpa.lib.rop.ResultList;
+import org.apache.openjpa.lib.util.Localizer;
+
+/**
+ * An implementation of the cache of {@link PreparedQuery prepared queries}. 
+ * 
+ * @author Pinaki Poddar
+ *
+ * @since 1.3.0
+ * @nojavadoc
+ */
+public class PreparedQueryCacheImpl implements PreparedQueryCache {
+	private static final String PATTERN_SEPARATOR = "\\;";
+	private static final String EXLUDED_BY_USER = "Excluded by user";
+
+	// Key: Query identifier 
+	private final Map<String, PreparedQuery> _delegate;
+	private final Map<Class, PreparedQuery> _finders;
+	// Key: Query identifier Value: Reason why excluded
+	private final Map<String, String> _uncachables;
+	private List<String> _exclusionPatterns;
+	private final QueryStatistics _stats;
+	private ReentrantLock _lock = new ReentrantLock();
+	private Log _log;
+	private Localizer _loc = Localizer.forPackage(PreparedQueryCacheImpl.class);
+
+	public PreparedQueryCacheImpl() {
+		_delegate = new HashMap<String, PreparedQuery>();
+		_finders = new HashMap<Class, PreparedQuery>();
+		_uncachables = new HashMap<String, String>();
+		_stats = new QueryStatistics.Default();
+	}
+	
+	public Boolean register(String id, Query query, FetchConfiguration hints) {
+        if (id == null 
+            || isHinted(hints, QueryHints.HINT_IGNORE_PREPARED_QUERY)
+            || isHinted(hints, QueryHints.HINT_INVALIDATE_PREPARED_QUERY))
+            return Boolean.FALSE;
+        if (isCachable(id) == Boolean.FALSE)
+            return Boolean.FALSE;
+        PreparedQuery cached = get(id);
+        if (cached != null)
+            return null; // implies that it is already cached
+        
+        PreparedQuery newEntry = new PreparedQueryImpl(id, query); 
+        return cache(newEntry);
+	}
+	
+	public Map<String,String> getMapView() {
+		lock();
+		try {
+			Map<String, String> view = new TreeMap<String, String>();
+			for (Map.Entry<String, PreparedQuery> entry : _delegate.entrySet())
+				view.put(entry.getKey(), entry.getValue().getTargetQuery());
+			return view;
+		} finally {
+			unlock();
+		}
+	}
+	
+
+	
+	/**
+	 * Cache the given query keyed by its identifier. Does not cache if the 
+	 * identifier matches any exclusion pattern or has been marked as 
+	 * non-cachable. Also register the identifier as not cachable against 
+	 * the matched exclusion pattern.
+	 */
+	public boolean cache(PreparedQuery q) {
+		lock();
+		try {
+			String id = q.getIdentifier();
+			if (isCachable(id) == Boolean.FALSE) {
+				if (_log != null && _log.isWarnEnabled())
+					_log.warn(_loc.get("prepared-query-not-cachable", id));
+				return false;
+			}
+			String pattern = getMatchedExclusionPattern(id);
+			if (pattern != null) {
+				markUncachable(q.getIdentifier(), pattern);
+				return false;
+			}
+			if (_log != null && _log.isTraceEnabled())
+				_log.trace(_loc.get("prepared-query-cache", q.getIdentifier(), 
+					q.getTargetQuery()));
+			_delegate.put(q.getIdentifier(), q);
+			return true;
+		} finally {
+			unlock();
+		}
+	}
+	
+    public PreparedQuery initialize(String key, Object result) {
+        PreparedQuery pq = get(key);
+        if (pq == null)
+            return null;
+        
+        boolean cacheable = pq.initialize(result);
+        if (!cacheable) {
+            markUncachable(key);
+            return null;
+        } 
+        return pq;
+    }
+
+	
+	public boolean invalidate(String id) {
+		lock();
+		try {
+			if (_log.isTraceEnabled())
+				_log.trace(_loc.get("prepared-query-invalidate", id));
+			return _delegate.remove(id) != null;
+		} finally {
+			unlock();
+		}
+	}
+	
+    public PreparedQuery get(String id) {
+        lock();
+        try {
+            return _delegate.get(id);
+        } finally {
+            unlock();
+        }
+    }
+    
+    public PreparedQuery get(Class c) {
+        lock();
+        try {
+            return _finders.get(c);
+        } finally {
+            unlock();
+        }
+    }
+	
+	public Boolean isCachable(String id) {
+		lock();
+		try {
+			if (_uncachables.containsKey(id))
+				return Boolean.FALSE;
+			if (_delegate.containsKey(id))
+				return Boolean.TRUE;
+			return null;
+		} finally {
+			unlock();
+		}
+	}
+	
+	public PreparedQuery markUncachable(String id) {
+		return markUncachable(id, EXLUDED_BY_USER);
+	}
+	
+	private PreparedQuery markUncachable(String id, String reason) {
+		lock();
+		try {
+			boolean excludedByUser = _uncachables.get(id) == EXLUDED_BY_USER;
+			if (!excludedByUser)
+				_uncachables.put(id, reason);
+			if (_log != null && _log.isInfoEnabled()) {
+				if (excludedByUser) 
+					_log.info(_loc.get("prepared-query-uncache-strong", id));
+				else 
+					_log.info(_loc.get("prepared-query-uncache-weak", id, 
+						reason));
+			}
+			return _delegate.remove(id);
+		} finally {
+			unlock();
+		}
+	}
+	
+	public boolean isExcluded(String id) {
+		return getMatchedExclusionPattern(id) != null;
+	}
+	
+	public void setExcludes(String excludes) {
+		lock();
+		try {
+			if (StringUtils.isEmpty(excludes))
+				return;
+			if (_exclusionPatterns == null)
+				_exclusionPatterns = new ArrayList<String>();
+			String[] patterns = excludes.split(PATTERN_SEPARATOR);
+			for (String pattern : patterns)
+				addExclusionPattern(pattern);
+		} finally {
+			unlock();
+		}
+	}
+
+	public List<String> getExcludes() {
+		return _exclusionPatterns == null ? Collections.EMPTY_LIST : 
+			Collections.unmodifiableList(_exclusionPatterns);
+	}
+	
+	/**
+	 * Adds a pattern for exclusion. Any query cached currently whose identifier
+	 * matches the given pattern will be marked invalidated as a side-effect.
+	 */
+	public void addExclusionPattern(String pattern) {
+		lock();
+		try {
+			if (_exclusionPatterns == null)
+				_exclusionPatterns = new ArrayList<String>();
+			_exclusionPatterns.add(pattern);
+			Collection<String> invalidKeys = getMatchedKeys(pattern, 
+					_delegate.keySet());
+			if (!invalidKeys.isEmpty() && _log != null && _log.isInfoEnabled())
+				_log.info(_loc.get("prepared-query-add-pattern", pattern, 
+					invalidKeys.size(), invalidKeys));
+			for (String invalidKey : invalidKeys)
+				markUncachable(invalidKey, pattern);
+		} finally {
+			unlock();
+		}
+	}
+	
+	/**
+	 * Removes a pattern for exclusion. Any query identifier marked as not 
+	 * cachable due to the given pattern will now be removed from the list of
+	 * uncachables as a side-effect.
+	 */
+	public void removeExclusionPattern(String pattern) {
+		lock();
+		try {
+			if (_exclusionPatterns == null)
+				return;
+			_exclusionPatterns.remove(pattern);
+			Collection<String> reborns = getMatchedKeys(pattern, _uncachables);
+			if (!reborns.isEmpty() && _log != null && _log.isInfoEnabled())
+				_log.info(_loc.get("prepared-query-remove-pattern", pattern, 
+					reborns.size(), reborns));
+			for (String rebornKey : reborns)
+				_uncachables.remove(rebornKey);
+		} finally {
+			unlock();
+		}
+	}
+	
+	public QueryStatistics getStatistics() {
+		return _stats;
+	}
+	
+	/**
+	 * Gets the pattern that matches the given identifier.
+	 */
+	private String getMatchedExclusionPattern(String id) {
+		lock();
+		try {
+			if (_exclusionPatterns == null || _exclusionPatterns.isEmpty())
+				return null;
+			for (String pattern : _exclusionPatterns)
+				if (matches(pattern, id))
+					return pattern;
+			return null;
+		} finally {
+			unlock();
+		}
+	}
+	
+	/**
+	 * Gets the keys of the given map whose values match the given pattern. 
+	 */
+	private Collection<String> getMatchedKeys(String pattern, 
+			Map<String,String> map) {
+		List<String> result = new ArrayList<String>();
+		for (Map.Entry<String, String> entry : map.entrySet()) {
+			if (matches(pattern, entry.getValue())) {
+				result.add(entry.getKey());
+			}
+		}
+		return result;
+	}
+	
+	/**
+	 * Gets the elements of the given list which match the given pattern. 
+	 */
+	private Collection<String> getMatchedKeys(String pattern, 
+			Collection<String> coll) {
+		List<String> result = new ArrayList<String>();
+		for (String key : coll) {
+			if (matches(pattern, key)) {
+				result.add(key);
+			}
+		}
+		return result;
+	}
+
+    void lock() {
+        if (_lock != null)
+            _lock.lock();
+    }
+
+    void unlock() {
+        if (_lock != null && _lock.isLocked())
+            _lock.unlock();
+    }
+    
+    boolean matches(String pattern, String target) {
+    	return target != null && (target.equals(pattern) 
+    	  || target.matches(pattern));
+    }
+    
+    boolean isHinted(FetchConfiguration fetch, String hint) {
+        if (fetch == null)
+            return false;
+        Object result = fetch.getHint(hint);
+        return result != null && "true".equalsIgnoreCase(result.toString());
+    }
+    
+
+    
+	//-------------------------------------------------------
+	// Configurable contract
+	//-------------------------------------------------------
+    public void setConfiguration(Configuration conf) {
+    	_log = conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);
+    }
+
+    public void startConfiguration() {
+    }
+
+    public void endConfiguration() {
+    }
+}

Added: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryImpl.java?rev=739123&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryImpl.java (added)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedQueryImpl.java Fri Jan 30 01:27:35 2009
@@ -0,0 +1,161 @@
+/*
+ * 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.jdbc.kernel;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.SelectExecutor;
+import org.apache.openjpa.kernel.PreparedQuery;
+import org.apache.openjpa.kernel.Query;
+import org.apache.openjpa.lib.rop.ResultList;
+
+public class PreparedQueryImpl implements PreparedQuery {
+    private final String _id;
+    private String _sql;
+    
+    // Post-compilation state of an executable query, populated on construction
+    private Class _candidate;
+    private boolean _subclasses;
+    private boolean _isProjection;
+    
+    // Parameters of the query
+    private List    _params;
+    private List    _userParams;
+    
+    
+    /**
+     * Construct.
+     * 
+     * @param id an identifier for this query to be used as cache key
+     * @param compiled a compiled query 
+     */
+    public PreparedQueryImpl(String id, Query compiled) {
+        this(id, null, compiled);
+    }
+    
+    /**
+     * Construct.
+     * 
+     * @param id an identifier for this query to be used as cache key
+     * @param corresponding data store language query string 
+     * @param compiled a compiled query 
+     */
+    public PreparedQueryImpl(String id, String sql, Query compiled) {
+        this._id = id;
+        this._sql = sql;
+        if (compiled != null) {
+            _candidate    = compiled.getCandidateType();
+            _subclasses   = compiled.hasSubclasses();
+            _isProjection = compiled.getProjectionAliases().length > 0;
+        }
+    }
+    
+    public String getIdentifier() {
+        return _id;
+    }
+    
+    public String getOriginalQuery() {
+        return getIdentifier();
+    }
+    
+    public String getTargetQuery() {
+        return _sql;
+    }
+    
+    public void setDatastoreAction(String sql) {
+        _sql = sql;
+    }
+    
+    /**
+     * Pours the post-compilation state held by this receiver to the given
+     * query.
+     */
+    public void setInto(Query q) {
+        if (!_isProjection)
+            q.setCandidateType(_candidate, _subclasses);
+    }
+    
+    public boolean initialize(Object result) {
+        boolean initialized = false;
+        if (result instanceof ResultList) {
+            Object provider = ((ResultList)result).getUserObject();
+            if (provider instanceof SelectResultObjectProvider) {
+                SelectResultObjectProvider rop = 
+                    (SelectResultObjectProvider)provider;
+                SelectExecutor selector = rop.getSelect();
+                SQLBuffer buffer = selector == null ? null : selector.getSQL();
+                if (buffer != null && !selector.hasMultipleSelects()) {
+                    setDatastoreAction(buffer.getSQL());
+                    setUserParameters(buffer.getUserParameters());
+                    setParameters(buffer.getParameters());
+                    initialized = true;
+                }
+            }
+        }
+        return initialized;
+    }
+    
+    /**
+     * Merge the given user parameters with its own parameter.
+     * 
+     * @return key index starting from 1 and corresponding values.
+     */
+    public Map<Integer, Object> reparametrize(Map user) {
+        Map<Integer, Object> result = new HashMap<Integer, Object>();
+        for (int i = 0; i < _params.size(); i++) {
+            result.put(i, _params.get(i));
+        }
+        if (user == null)
+            return result;
+        for (Object key : user.keySet()) {
+            List<Integer> indices = findUserParameterPositions(key);
+            for (int j : indices)
+                result.put(j, user.get(key));
+        }
+        return result;
+    }
+    
+    private List<Integer> findUserParameterPositions(Object key) {
+        List<Integer> result = new ArrayList<Integer>();
+        for (int i = 1; _userParams != null && i < _userParams.size(); i+=2) {
+            if (_userParams.get(i).equals(key))
+                result.add((Integer)_userParams.get(i-1));
+        }
+        return result;
+    }
+    
+    void setUserParameters(List list) {
+        _userParams = list;
+    }
+    
+    void setParameters(List list) {
+        _params = list;
+    }
+    
+    public String toString() {
+        return "PreparedQuery: [" + getOriginalQuery() + "] --> [" + 
+               getTargetQuery() + "]";
+    }
+
+}

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/CollectionParam.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/CollectionParam.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/CollectionParam.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/CollectionParam.java Fri Jan 30 01:27:35 2009
@@ -43,7 +43,7 @@
     private static final Localizer _loc = Localizer.forPackage(
         CollectionParam.class);
 
-    private final String _name;
+    private final Object _key;
     private Class _type = null;
     private int _idx = -1;
     private boolean _container = false;
@@ -51,17 +51,13 @@
     /**
      * Constructor. Supply parameter name and type.
      */
-    public CollectionParam(String name, Class type) {
-        _name = name;
+    public CollectionParam(Object key, Class type) {
+        _key = key;
         setImplicitType(type);
     }
 
-    public String getName() {
-        return _name;
-    }
-
-    public String getParameterName() {
-        return getName();
+    public Object getParameterKey() {
+        return _key;
     }
 
     public Class getType() {
@@ -143,11 +139,11 @@
 
         if (!(value instanceof Collection))
             throw new IllegalArgumentException(_loc.get(
-                "not-collection-parm", _name).toString());
+                "not-collection-parm", _key).toString());
 
         if (((Collection) value).isEmpty())
             throw new IllegalArgumentException(_loc.get(
-                "empty-collection-parm", _name).toString());
+                "empty-collection-parm", _key).toString());
 
         Iterator itr = ((Collection) value).iterator();
         for (int i = 0; i < pstate.size && itr.hasNext(); i++) {
@@ -182,13 +178,13 @@
         for (int i = 0; i < pstate.size; i++) {
             if (pstate.otherLength[i] > 1)
                 sql.appendValue(((Object[]) pstate.sqlValue[i])[index], 
-                        pstate.getColumn(index));
+                        pstate.getColumn(index), this);
             else if (pstate.cols != null)
-                sql.appendValue(pstate.sqlValue[i], pstate.getColumn(index));
+                sql.appendValue(pstate.sqlValue[i], pstate.getColumn(index), this);
             else if (pstate.discValue[i] != null)
                 sql.appendValue(pstate.discValue[i]);
             else
-                sql.appendValue(pstate.sqlValue[i], pstate.getColumn(index));
+                sql.appendValue(pstate.sqlValue[i], pstate.getColumn(index), this);
         }
     }
 }

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java Fri Jan 30 01:27:35 2009
@@ -271,12 +271,12 @@
         return CURRENT_TIMESTAMP;
     }
 
-    public Parameter newParameter(String name, Class type) {
+    public Parameter newParameter(Object name, Class type) {
         return new Param(name, type);
     }
 
-    public Parameter newCollectionValuedParameter(String name, Class type) {
-        return new CollectionParam(name, type);
+    public Parameter newCollectionValuedParameter(Object key, Class type) {
+        return new CollectionParam(key, type);
     }
 
     public Value newExtension(FilterListener listener, Value target,

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java Fri Jan 30 01:27:35 2009
@@ -38,7 +38,7 @@
     extends Const
     implements Parameter {
 
-    private final String _name;
+    private final Object _key;
     private Class _type = null;
     private int _idx = -1;
     private boolean _container = false;
@@ -46,17 +46,13 @@
     /**
      * Constructor. Supply parameter name and type.
      */
-    public Param(String name, Class type) {
-        _name = name;
+    public Param(Object key, Class type) {
+        _key = key;
         setImplicitType(type);
     }
 
-    public String getName() {
-        return _name;
-    }
-
-    public String getParameterName() {
-        return getName();
+    public Object getParameterKey() {
+        return _key;
     }
 
     public Class getType() {
@@ -142,12 +138,12 @@
         ParamExpState pstate = (ParamExpState) state;
         if (pstate.otherLength > 1)
             sql.appendValue(((Object[]) pstate.sqlValue)[index], 
-                pstate.getColumn(index));
+                pstate.getColumn(index), this);
         else if (pstate.cols != null)
-            sql.appendValue(pstate.sqlValue, pstate.getColumn(index));
+            sql.appendValue(pstate.sqlValue, pstate.getColumn(index), this);
         else if (pstate.discValue != null)
             sql.appendValue(pstate.discValue);
         else
-            sql.appendValue(pstate.sqlValue, pstate.getColumn(index));
+            sql.appendValue(pstate.sqlValue, pstate.getColumn(index), this);
     }
 }

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java Fri Jan 30 01:27:35 2009
@@ -19,9 +19,7 @@
 package org.apache.openjpa.jdbc.meta.strats;
 
 import java.sql.SQLException;
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -29,9 +27,7 @@
 import org.apache.openjpa.enhance.ReflectingPersistenceCapable;
 import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
 import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
-import org.apache.openjpa.jdbc.kernel.JDBCFetchConfigurationImpl;
 import org.apache.openjpa.jdbc.kernel.JDBCStore;
-import org.apache.openjpa.jdbc.kernel.JDBCStoreManager;
 import org.apache.openjpa.jdbc.meta.ClassMapping;
 import org.apache.openjpa.jdbc.meta.Embeddable;
 import org.apache.openjpa.jdbc.meta.FieldMapping;
@@ -47,14 +43,12 @@
 import org.apache.openjpa.jdbc.schema.Table;
 import org.apache.openjpa.jdbc.sql.DBDictionary;
 import org.apache.openjpa.jdbc.sql.Joins;
-import org.apache.openjpa.jdbc.sql.LogicalUnion;
 import org.apache.openjpa.jdbc.sql.Result;
 import org.apache.openjpa.jdbc.sql.Row;
 import org.apache.openjpa.jdbc.sql.RowManager;
 import org.apache.openjpa.jdbc.sql.SQLBuffer;
 import org.apache.openjpa.jdbc.sql.Select;
 import org.apache.openjpa.jdbc.sql.SelectExecutor;
-import org.apache.openjpa.jdbc.sql.SelectImpl;
 import org.apache.openjpa.jdbc.sql.Union;
 import org.apache.openjpa.kernel.OpenJPAStateManager;
 import org.apache.openjpa.lib.log.Log;
@@ -68,7 +62,6 @@
 import org.apache.openjpa.util.MetaDataException;
 import org.apache.openjpa.util.OpenJPAId;
 import org.apache.openjpa.util.UnsupportedException;
-
 import serp.util.Numbers;
 
 /**
@@ -686,97 +679,9 @@
         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 {
-            Map<JDBCStoreManager.SelectKey, Object[]> 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) {
+        // 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 union = store.getSQLFactory().newUnion(rels.length);
         union.setExpectedResultCount(1, false);
         if (fetch.getSubclassFetchMode(field.getTypeMapping())
@@ -797,7 +702,17 @@
                     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/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java Fri Jan 30 01:27:35 2009
@@ -60,9 +60,6 @@
 public abstract class StoreCollectionFieldStrategy
     extends ContainerFieldStrategy {
 
-    private static final Localizer _loc = Localizer.forPackage
-        (StoreCollectionFieldStrategy.class);
-    
     /**
      * Return the foreign key used to join to the owning field for the given
      * element mapping from {@link #getIndependentElementMappings} (or null).

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java Fri Jan 30 01:27:35 2009
@@ -129,6 +129,10 @@
     public SQLBuffer toSelect(boolean forUpdate, JDBCFetchConfiguration fetch) {
         return dict.toSelect(sels[0], forUpdate, fetch);
     }
+    
+    public SQLBuffer getSQL() {
+        return sels.length == 1 ? sels[0].getSQL() : null;
+    }
 
     public SQLBuffer toSelectCount() {
         return dict.toSelectCount(sels[0]);
@@ -194,6 +198,13 @@
         return true;
     }
 
+    public boolean hasMultipleSelects() {
+        for (UnionSelect sel : sels)
+            if (sel.hasMultipleSelects())
+                return true;
+        return false;
+    }
+
     public int getCount(JDBCStore store)
         throws SQLException {
         int count = 0;
@@ -203,32 +214,20 @@
     }
 
     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)
             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;
         }
@@ -237,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);
 
@@ -269,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);
 
@@ -316,7 +315,7 @@
     /**
      * A select that is part of a logical union.
      */
-    public class UnionSelect
+    protected class UnionSelect
         implements Select {
 
         protected final SelectImpl sel;
@@ -359,6 +358,10 @@
             JDBCFetchConfiguration fetch) {
             return sel.toSelect(forUpdate, fetch);
         }
+        
+        public SQLBuffer getSQL() {
+            return sel.getSQL();
+        }
 
         public SQLBuffer toSelectCount() {
             return sel.toSelectCount();
@@ -404,21 +407,13 @@
             return sel.supportsLocking();
         }
 
-        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 boolean hasMultipleSelects() {
+            return sel.hasMultipleSelects();
         }
 
-        public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
-            int lockLevel, List params)
+        public int getCount(JDBCStore store)
             throws SQLException {
-            return sel.execute(store, fetch, lockLevel, params);
+            return sel.getCount(store);
         }
 
         public Result execute(JDBCStore store, JDBCFetchConfiguration fetch)
@@ -431,7 +426,7 @@
             throws SQLException {
             return sel.execute(store, fetch, lockLevel);
         }
-        
+
         public List getSubselects() {
             return Collections.EMPTY_LIST;
         }
@@ -500,14 +495,6 @@
             return sel.getHaving();
         }
 
-        public SQLBuffer getSQL() {
-            return sel.getSQL();
-        }
-        
-        public void setSQL(JDBCStore store, JDBCFetchConfiguration fetch) {
-            sel.setSQL(store, fetch);
-        }
-        
         public void addJoinClassConditions() {
             sel.addJoinClassConditions();
         }
@@ -755,15 +742,6 @@
             JDBCStore store) {
             sel.wherePrimaryKey(oid, mapping, store);
         }
-        
-        public int wherePrimaryKey(ClassMapping mapping, Column[] toCols, 
-            Column[] fromCols, Object oid, JDBCStore store, PathJoins pj,
-            SQLBuffer buf, List parmList) {
-            return sel.wherePrimaryKey(mapping, toCols, fromCols, oid, store, pj, 
-                buf, parmList);
-        }
-        
-        
 
         public void whereForeignKey(ForeignKey fk, Object oid,
             ClassMapping mapping, JDBCStore store) {

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java Fri Jan 30 01:27:35 2009
@@ -33,17 +33,23 @@
 import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
 import org.apache.openjpa.jdbc.kernel.exps.Val;
 import org.apache.openjpa.jdbc.schema.Column;
-import org.apache.openjpa.jdbc.schema.ForeignKey;
 import org.apache.openjpa.jdbc.schema.Sequence;
 import org.apache.openjpa.jdbc.schema.Table;
+import org.apache.openjpa.kernel.exps.Parameter;
+
 import serp.util.Numbers;
 
 /**
  * Buffer for SQL statements that can be used to create
  * java.sql.PreparedStatements.
+ * This buffer holds the SQL statement parameters and their corresponding 
+ * columns. The parameters introduced by the runtime system are distinguished
+ * from the parameters set by the user.  
  *
  * @author Marc Prud'hommeaux
  * @author Abe White
+ * @author Pinaki Poddar
+ * 
  * @since 0.2.4
  */
 public final class SQLBuffer
@@ -56,7 +62,11 @@
     private List _subsels = null;
     private List _params = null;
     private List _cols = null;
-
+    
+    // Odd element refers to an index of the _params list
+    // Even element refers to the user parameter key
+    private List _userIndex = null;
+    
     /**
      * Default constructor.
      */
@@ -146,6 +156,16 @@
                         _cols.add(paramIndex, null);
             }
         }
+        if (buf._userIndex != null) {
+            if (_userIndex == null)
+                _userIndex = new ArrayList();
+            for (int i = 0; i < buf._userIndex.size(); i+=2) {
+                int newIndex = ((Integer)buf._userIndex.get(i)).intValue() + paramIndex;
+                Object userParam = buf._userIndex.get(i+1);
+                _userIndex.add(newIndex);
+                _userIndex.add(userParam);
+            }
+        }
     }
 
     public SQLBuffer append(Table table) {
@@ -225,11 +245,21 @@
     public SQLBuffer appendValue(Object o) {
         return appendValue(o, null);
     }
-
+    
     /**
-     * Append a parameter value for a specific column.
+     * Append a system inserted parameter value for a specific column.
      */
     public SQLBuffer appendValue(Object o, Column col) {
+        return appendValue(o, col, null);
+    }
+    
+    /**
+     * Append a user parameter value for a specific column.
+     * 
+     * @param userParam if non-null, designates the user parameter from a
+     * Query Expression tree.
+     */
+    public SQLBuffer appendValue(Object o, Column col, Parameter userParam) {
         if (o == null)
             _sql.append("NULL");
         else if (o instanceof Raw)
@@ -248,23 +278,15 @@
             }
 
             _params.add(o);
+            if (userParam != null) {
+                if (_userIndex == null)
+                    _userIndex = new ArrayList();
+                int index = _params.size()-1;
+                _userIndex.add(index);
+                _userIndex.add(userParam.getParameterKey());
+            }
             if (_cols != null)
                 _cols.add(col);
-            if (col == null)
-                return this;
-            boolean isFK = false;
-            ForeignKey[] fks = col.getTable().getForeignKeys();
-            for (int i = 0; i < fks.length; i++) {
-                Column[] cols = fks[i].getColumns();
-                for (int j = 0; j < cols.length; j++) {
-                    if (cols[j] == col) {
-                        isFK = true;
-                        break;
-                    }
-                }
-                if (isFK)
-                    break;
-            }
         }
         return this;
     }
@@ -387,6 +409,20 @@
     public List getParameters() {
         return (_params == null) ? Collections.EMPTY_LIST : _params;
     }
+    
+    /**
+     * Get the user parameter positions in the list of parameters. The odd 
+     * element of the returned list contains an integer index that refers
+     * to the position in the {@link #getParameters()} list. The even element
+     * of the returned list refers to the user parameter key. 
+     * This structure is preferred over a normal map because a user parameter 
+     * may occur more than one in the parameters. 
+     */
+    public List getUserParameters() {
+        if (_userIndex == null)
+            return Collections.EMPTY_LIST;
+        return _userIndex;
+    }
 
     /**
      * Return the SQL for this buffer.
@@ -466,19 +502,9 @@
      * the SQL in this buffer.
      */
     public PreparedStatement prepareStatement(Connection conn, int rsType,
-        int rsConcur, List parms)
-        throws SQLException {
-        return prepareStatement(conn, null, rsType, rsConcur, parms);
-    }
-    
-    /**
-     * Create and populate the parameters of a prepared statement using
-     * the SQL in this buffer.
-     */
-    public PreparedStatement prepareStatement(Connection conn, int rsType,
         int rsConcur)
         throws SQLException {
-        return prepareStatement(conn, rsType, rsConcur, null);
+        return prepareStatement(conn, null, rsType, rsConcur);
     }
 
     /**
@@ -488,16 +514,6 @@
     public PreparedStatement prepareStatement(Connection conn,
         JDBCFetchConfiguration fetch, int rsType, int rsConcur)
         throws SQLException {
-        return prepareStatement(conn, fetch, rsType, rsConcur, null);
-    }
-    
-    /**
-     * Create and populate the parameters of a prepred statement using the
-     * SQL in this buffer and the given fetch configuration.
-     */
-    public PreparedStatement prepareStatement(Connection conn,
-        JDBCFetchConfiguration fetch, int rsType, int rsConcur, List parms)
-        throws SQLException {
         if (rsType == -1 && fetch == null)
             rsType = ResultSet.TYPE_FORWARD_ONLY;
         else if (rsType == -1)
@@ -512,7 +528,7 @@
         else
             stmnt = conn.prepareStatement(getSQL(), rsType, rsConcur);
         try {
-            setParameters(stmnt, parms);
+            setParameters(stmnt);
             if (fetch != null) {
                 if (fetch.getFetchBatchSize() > 0)
                     stmnt.setFetchSize(fetch.getFetchBatchSize());
@@ -595,25 +611,13 @@
      */
     public void setParameters(PreparedStatement ps)
         throws SQLException {
-        setParameters(ps, null);
-    }
-    
-    /**
-     * Populate the parameters of an existing PreparedStatement
-     * with values from this buffer.
-     */
-    public void setParameters(PreparedStatement ps, List cacheParams)
-        throws SQLException {
-        List params = ((cacheParams != null && cacheParams.size() > 0) ? 
-            cacheParams : _params);    
-        
-        if (params == null)
+        if (_params == null)
             return;
 
         Column col;
-        for (int i = 0; i < params.size(); i++) {
+        for (int i = 0; i < _params.size(); i++) {
             col = (_cols == null) ? null : (Column) _cols.get(i);
-            _dict.setUnknown(ps, i + 1, params.get(i), col);
+            _dict.setUnknown(ps, i + 1, _params.get(i), col);
         }
     }
 

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java Fri Jan 30 01:27:35 2009
@@ -194,19 +194,6 @@
     public SQLBuffer getHaving();
 
     /**
-     * Return the SQL for this select. This buffer contains
-     * the final SQL to be executed/cached.
-     */
-    public SQLBuffer getSQL();    
-    
-    /**
-     * Create and set the SQLBuffer object to this select. This buffer contains
-     * the final SQL to be executed/cached.
-     */
-    public void setSQL(JDBCStore store, JDBCFetchConfiguration fetch); 
-    
-    
-    /**
      * Apply class conditions from relation joins.  This may affect the return
      * values of {@link #getJoins}, {@link #getJoinIterator}, and
      * {@link #getWhere}.
@@ -529,19 +516,6 @@
      */
     public void wherePrimaryKey(Object oid, ClassMapping mapping,
         JDBCStore store);
-    
-    
-    /**
-     * Add where conditions setting the mapping's primary key to the given
-     * oid values. If the parmList is not null, the value of the primary
-     * key will be collected and saved into the parmList. If the parmList is 
-     * null, this method will build the where clause with the value
-     * incorporated in the where clause.
-     */
-    public int wherePrimaryKey(ClassMapping mapping, Column[] toCols, 
-            Column[] fromCols, Object oid, JDBCStore store, PathJoins pj,
-            SQLBuffer buf, List parmList);
-    
 
     /**
      * Add where conditions setting the given foreign key to the given

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java Fri Jan 30 01:27:35 2009
@@ -19,7 +19,6 @@
 package org.apache.openjpa.jdbc.sql;
 
 import java.sql.SQLException;
-import java.util.List;
 
 import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
 import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
@@ -42,6 +41,14 @@
      * dictionary.
      */
     public SQLBuffer toSelect(boolean forUpdate, JDBCFetchConfiguration fetch);
+    
+    /**
+     * Get the buffer if it has been computed by a previous call to 
+     * {@link #toSelect(boolean, JDBCFetchConfiguration)}, if any.
+     * 
+     * @since 2.0.0
+     */
+    public SQLBuffer getSQL();
 
     /**
      * Return this select as a COUNT SQL statement formatted for the current
@@ -134,20 +141,14 @@
      * Execute this select in the context of the given store manager.
      */
     public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
-        List params) 
-        throws SQLException;
-
-    /**
-     * Execute this select in the context of the given store manager.
-     */
-    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
-        int lockLevel, List params)
+        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. 
+     * 
+     * @since 2.0.0
      */
-    public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
-        int lockLevel)
-        throws SQLException;
+    public boolean hasMultipleSelects();
 }

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java Fri Jan 30 01:27:35 2009
@@ -145,6 +145,7 @@
     private SQLBuffer _where = null;
     private SQLBuffer _grouping = null;
     private SQLBuffer _having = null;
+    private SQLBuffer _full = null;
 
     // joins to add to the end of our where clause, and joins to prepend to
     // all selects (see select(classmapping) method)
@@ -171,10 +172,7 @@
     // if the bit is set, the corresponding alias has been removed from parent
     // and recorded under subselect.
     private BitSet _removedAliasFromParent = new BitSet(16);
-
-    //contains final sql statement to be executed/cached
-    private SQLBuffer _sql = null;
-    
+     
     /**
      * Helper method to return the proper table alias for the given alias index.
      */
@@ -217,7 +215,12 @@
     }
 
     public SQLBuffer toSelect(boolean forUpdate, JDBCFetchConfiguration fetch) {
-        return _dict.toSelect(this, forUpdate, fetch);
+        _full = _dict.toSelect(this, forUpdate, fetch);
+        return _full;
+    }
+    
+    public SQLBuffer getSQL() {
+        return _full;
     }
 
     public SQLBuffer toSelectCount() {
@@ -296,6 +299,18 @@
         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 {
         Connection conn = null;
@@ -307,7 +322,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)
@@ -319,31 +334,20 @@
         }
     }
 
-    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);
     }
 
     /**
@@ -351,21 +355,16 @@
      * 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);
-        
-        // A non-null _sql indicates that this SelectImpl object
-        // is obtained from cache. The _sql is constructed
-        // under the assumption that isAggregate() is false
-        // and _grouping is null. If neither of these holds,
-        // we need to re-construct the _sql
-        if (_sql != null && (isAggregate() || _grouping != null)) 
-            _sql = null;
-        
-        if (_sql == null) 
-        	_sql = toSelect(forUpdate, fetch);
-        
+        boolean forUpdate = false;
+        if (!isAggregate() && _grouping == null) {
+            JDBCLockManager lm = store.getLockManager();
+            if (lm != null)
+                forUpdate = lm.selectForUpdate(this, lockLevel);
+        }
+
+        SQLBuffer sql = toSelect(forUpdate, fetch);
         boolean isLRS = isLRS();
         int rsType = (isLRS && supportsRandomAccess(forUpdate))
             ? -1 : ResultSet.TYPE_FORWARD_ONLY;
@@ -374,15 +373,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)
@@ -390,19 +387,7 @@
             try { conn.close(); } catch (SQLException se2) {}
             throw se;
         }
-
-        return getEagerResult(conn, stmnt, rs, store, fetch, forUpdate, 
-            _sql.getSQL(), params);
-    }
-    
-    private boolean isForUpdate(JDBCStore store, int lockLevel) {
-    	boolean forUpdate = false;
-        if (!isAggregate() && _grouping == null) {
-            JDBCLockManager lm = store.getLockManager();
-            if (lm != null)
-                forUpdate = lm.selectForUpdate(this, lockLevel);
-        }
-        return forUpdate;
+        return getEagerResult(conn, stmnt, rs, store, fetch, forUpdate, sql);
     }
 
     /**
@@ -410,7 +395,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;
@@ -429,7 +414,7 @@
                 eres = res;
             else
                 eres = ((SelectExecutor) entry.getValue()).execute(store,
-                    fetch, params);
+                    fetch);
 
             eager = res.getEagerMap(false);
             if (eager == null) {
@@ -448,22 +433,10 @@
     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);
-    }
-
-    /**
-     * 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, List params) 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);
     }
     
     /**
@@ -492,8 +465,7 @@
      * implementation of executing query.
      */
     protected ResultSet executeQuery(Connection conn, PreparedStatement stmnt, 
-        SQLBuffer sql, boolean isLRS, JDBCStore store, List params) 
-        throws SQLException {
+        SQLBuffer sql, boolean isLRS, JDBCStore store) throws SQLException {
         return stmnt.executeQuery();
     }
     
@@ -512,15 +484,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;
@@ -710,19 +681,6 @@
         return _having;
     }
 
-    public SQLBuffer getSQL() {
-        return _sql;
-    }
-
-    public void setSQL(SQLBuffer sql) {
-        _sql = sql;
-    }
-
-    public void setSQL(JDBCStore store, JDBCFetchConfiguration fetch) {
-        boolean forUpdate = isForUpdate(store, fetch.getReadLockLevel());
-        _sql = toSelect(forUpdate, fetch);
-    }
-    
     public void addJoinClassConditions() {
         if (_joins == null || _joins.joins() == null)
             return;
@@ -1437,38 +1395,12 @@
             return;
         }
 
-        SQLBuffer buf = new SQLBuffer(_dict);
-
-        // only bother to pack pk values into array if app id        
-        int count = wherePrimaryKey(mapping, toCols, fromCols, oid, store, pj, 
-        	buf, null);
-            	
-        if (constCols != null && constCols.length > 0) {
-            for (int i = 0; i < constCols.length; i++, count++) {
-                if (count > 0)
-                    buf.append(" AND ");
-                buf.append(getColumnAlias(constCols[i], pj));
-
-                if (vals[i] == null)
-                    buf.append(" IS ");
-                else
-                    buf.append(" = ");
-                buf.appendValue(vals[i], constCols[i]);
-            }
-        }
-
-        where(buf, pj);
-    }
-
-    public int wherePrimaryKey(ClassMapping mapping, Column[] toCols, 
-    	Column[] fromCols, Object oid, JDBCStore store, PathJoins pj,
-    	SQLBuffer buf, List parmList) {
         // only bother to pack pk values into array if app id
-    	boolean collectParmValueOnly = (parmList != null ? true : false);
         Object[] pks = null;
         if (mapping.getIdentityType() == ClassMapping.ID_APPLICATION)
             pks = ApplicationIds.toPKValues(oid, mapping);
 
+        SQLBuffer buf = new SQLBuffer(_dict);
         Joinable join;
         Object val;
         int count = 0;
@@ -1481,13 +1413,8 @@
                 val = pks[mapping.getField(join.getFieldIndex()).
                     getPrimaryKeyIndex()];
                 val = join.getJoinValue(val, toCols[i], store);
-                if (parmList != null)
-                	parmList.add(val);
             }
-            
-            if (collectParmValueOnly) 
-            	continue;
-            
+
             if (count > 0)
                 buf.append(" AND ");
             buf.append(getColumnAlias(fromCols[i], pj));
@@ -1497,9 +1424,24 @@
                 buf.append(" = ");
             buf.appendValue(val, fromCols[i]);
         }
-        return count;
+
+        if (constCols != null && constCols.length > 0) {
+            for (int i = 0; i < constCols.length; i++, count++) {
+                if (count > 0)
+                    buf.append(" AND ");
+                buf.append(getColumnAlias(constCols[i], pj));
+
+                if (vals[i] == null)
+                    buf.append(" IS ");
+                else
+                    buf.append(" = ");
+                buf.appendValue(vals[i], constCols[i]);
+            }
+        }
+
+        where(buf, pj);
     }
-    
+
     /**
      * Test to see if the given set of columns contains all the
      * columns in the given potential subset.
@@ -2235,7 +2177,7 @@
         }
         return aliases;
     }
-
+    
     public String toString() {
         return toSelect(false, null).getSQL();
     }

Modified: openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties Fri Jan 30 01:27:35 2009
@@ -115,6 +115,3 @@
 batch_limit: The batch limit is set to {0}.
 batch_update_info: ExecuteBatch command returns update count {0} for \
 	statement {1}.
-cache-hit: SQL Cache hit with key: {0} in {1}
-cache-missed: SQL Cache missed with key: {0} in {1}    
-sql-warning: The statement resulted in SQL warning: {0}

Modified: openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties?rev=739123&r1=739122&r2=739123&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/meta/strats/localizer.properties Fri Jan 30 01:27:35 2009
@@ -134,9 +134,6 @@
 	its "{1}" primary key field does not use a simple mapping.
 unmapped-datastore-value: Instances of type "{0}" are not valid query \
 	parameters because the type is not mapped.
-cache-hit: SQL Cache hit with key: {0} in {1}
-cache-missed: SQL Cache missed with key: {0} in {1}
-cant-set-value: Field "{1}" of "{0}" can not be set to "{2}" value.
 multi-column-version-unsupported:You have specified more than one column for \
 	version data, but the "{1}" version strategy does not support multi-column \
-	versioning.
\ No newline at end of file
+	versioning.