You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by Michael Dick <mi...@gmail.com> on 2008/05/05 17:32:07 UTC
Re: svn commit: r652913 - 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/meta/strats/ openjpa-jdbc/src/main/jav
I think it was the WebSphere UOW code I committed earlier that caused the
problem. Anyway it should be fixed with rev 653499. I had to exclude the
internal repository directory from the rat scan.
Note that the excludes won't work if you run :
$ mvn rat:check
but will work if you run :
$ mvn -Plicense-verify-profile rat:check
-mike
On Fri, May 2, 2008 at 10:16 PM, Patrick Linskey <pl...@gmail.com> wrote:
> Hi,
>
> This is failing the license header check test in the snapshot build.
>
> -Patrick
>
>
> On May 2, 2008, at 2:09 PM, mikedd@apache.org wrote:
>
> Author: mikedd
> > Date: Fri May 2 14:09:14 2008
> > New Revision: 652913
> >
> > URL: http://svn.apache.org/viewvc?rev=652913&view=rev
> > Log:
> > OPENJPA-407 committing patch provided by Fay Wang and Jeremy Bauer
> >
> > Added:
> >
> > openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/QuerySQLCacheValue.java
> > (with props)
> >
> > openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestQuerySQLCache.java
> > (with props)
> > 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/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/kernel/FetchConfigurationImpl.java
> > openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml
> > openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_conf.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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -18,6 +18,8 @@
> > */
> > package org.apache.openjpa.jdbc.conf;
> >
> > +import java.util.Map;
> > +
> > import javax.sql.DataSource;
> >
> > import org.apache.openjpa.conf.OpenJPAConfiguration;
> > @@ -602,4 +604,23 @@
> > * @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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -20,6 +20,9 @@
> >
> > 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;
> > @@ -82,6 +85,8 @@
> > public ObjectValue mappingDefaultsPlugin;
> > public PluginValue driverDataSourcePlugin;
> > public MappingFactoryValue mappingFactoryPlugin;
> > + public QuerySQLCacheValue querySQLCache;
> > + private Map querySQLCacheInstance = new HashMap();
> >
> > // used internally
> > private String firstUser = null;
> > @@ -302,6 +307,9 @@
> > seqPlugin.setDefault(JDBCSeqValue.ALIASES[0]);
> > seqPlugin.setString(JDBCSeqValue.ALIASES[0]);
> >
> > + querySQLCache = new QuerySQLCacheValue("jdbc.QuerySQLCache");
> > + addValue(querySQLCache);
> > +
> > // this static initializer is to get past a weird
> > // ClassCircularityError that happens only under IBM's
> > // JDK 1.3.1 on Linux from within the JRun ClassLoader;
> > @@ -856,4 +864,21 @@
> > 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;
> > + }
> > +
> > }
> >
> > Added:
> > openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/QuerySQLCacheValue.java
> > URL:
> > http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/QuerySQLCacheValue.java?rev=652913&view=auto
> >
> > ==============================================================================
> > ---
> > openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/QuerySQLCacheValue.java
> > (added)
> > +++
> > openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/QuerySQLCacheValue.java
> > Fri May 2 14:09:14 2008
> > @@ -0,0 +1,86 @@
> > +/*
> > + * 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.conf;
> > +
> > +import java.util.Collections;
> > +import java.util.Hashtable;
> > +import java.util.Map;
> > +import java.util.concurrent.ConcurrentHashMap;
> > +
> > +import org.apache.openjpa.lib.conf.Configurations;
> > +import org.apache.openjpa.lib.conf.PluginValue;
> > +import org.apache.openjpa.util.CacheMap;
> > +
> > +
> > +/**
> > + * A cache of sql queries.
> > + *
> > + * @since 1.2
> > + * @nojavadoc
> > + */
> > +public class QuerySQLCacheValue
> > + extends PluginValue {
> > +
> > + public static final String[] ALIASES = {
> > + "true", CacheMap.class.getName(),
> > + "all", ConcurrentHashMap.class.getName(),
> > + "false", null,
> > + };
> > +
> > + public QuerySQLCacheValue(String prop) {
> > + super(prop, true);
> > + setAliases(ALIASES);
> > + setDefault(ALIASES[0]);
> > + setClassName(ALIASES[1]);
> > + }
> > +
> > + public boolean isSQLCacheOn() {
> > + if (getClassName() == null)
> > + return false;
> > + return true;
> > + }
> > +
> > + public Object newInstance() {
> > + // make sure map handles concurrency
> > + String clsName = getClassName();
> > + if (clsName == null)
> > + return null;
> > + Map map = null;
> > +
> > + try {
> > + // Use the "OpenJPA" classloader first...
> > + map = (Map) Configurations.newInstance(clsName,
> > this.getClass()
> > + .getClassLoader());
> > + } catch (Exception e) {
> > + // If the "OpenJPA" classloader fails, then try the
> > classloader
> > + // that was used to load java.util.Map...
> > + map = (Map) Configurations.newInstance(clsName,
> > + Map.class.getClassLoader());
> > + }
> > + if (map != null
> > + && !(map instanceof Hashtable)
> > + && !(map instanceof CacheMap)
> > + && !(map instanceof
> > +
> > org.apache.openjpa.lib.util.concurrent.ConcurrentMap)
> > + && !(map instanceof
> > java.util.concurrent.ConcurrentMap))
> > + map = Collections.synchronizedMap(map);
> > + return map;
> > + }
> > +
> > +}
> >
> > Propchange:
> > openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/QuerySQLCacheValue.java
> >
> > ------------------------------------------------------------------------------
> > svn:eol-style = native
> >
> > 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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -29,15 +29,20 @@
> > 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.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;
> > @@ -60,10 +65,12 @@
> > 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;
> > @@ -99,7 +106,11 @@
> >
> > // 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;
> > }
> > @@ -125,6 +136,9 @@
> >
> > if (_conf.getUpdateManagerInstance().orderDirty())
> > ctx.setOrderDirtyObjects(true);
> > +
> > + _sqlCache = _conf.getQuerySQLCacheInstance();
> > + _isQuerySQLCache = _conf.isQuerySQLCacheOn();
> > }
> >
> > public JDBCConfiguration getConfiguration() {
> > @@ -402,13 +416,86 @@
> > 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.execute(this, fetch);
> > + return sel;
> > }
> >
> > /**
> > @@ -1419,4 +1506,163 @@
> > }
> > }
> > }
> > +
> > + 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;
> > + }
> > + }
> > }
> >
> > 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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -19,11 +19,16 @@
> > 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 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;
> > @@ -38,12 +43,14 @@
> > 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;
> > @@ -55,6 +62,7 @@
> > import org.apache.openjpa.util.MetaDataException;
> > import org.apache.openjpa.util.OpenJPAId;
> > import org.apache.openjpa.util.UnsupportedException;
> > +
> > import serp.util.Numbers;
> >
> > /**
> > @@ -579,9 +587,97 @@
> > final int subs = field.getSelectSubclasses();
> > final Joins[] resJoins = new Joins[rels.length];
> >
> > - // 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)
> > + //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) {
> > Union union = store.getSQLFactory().newUnion(rels.length);
> > union.setExpectedResultCount(1, false);
> > if (fetch.getSubclassFetchMode(field.getTypeMapping())
> > @@ -602,17 +698,7 @@
> > resJoins[idx]);
> > }
> > });
> > -
> > - 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();
> > - }
> > + return union;
> > }
> >
> > 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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -22,21 +22,29 @@
> > import java.util.ArrayList;
> > import java.util.Collection;
> > import java.util.HashMap;
> > +import java.util.List;
> > import java.util.Map;
> >
> > +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.FieldMapping;
> > import org.apache.openjpa.jdbc.meta.FieldStrategy;
> > import org.apache.openjpa.jdbc.schema.Column;
> > import org.apache.openjpa.jdbc.schema.ForeignKey;
> > 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.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;
> > +import org.apache.openjpa.lib.util.Localizer;
> > import org.apache.openjpa.meta.JavaTypes;
> > import org.apache.openjpa.util.ChangeTracker;
> > import org.apache.openjpa.util.Id;
> > @@ -55,6 +63,9 @@
> > 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).
> > @@ -445,19 +456,83 @@
> > return;
> > }
> >
> > + //cache union for field here
> > // select data for this sm
> > + boolean found = true;
> > final ClassMapping[] elems = getIndependentElementMappings(true);
> > final Joins[] resJoins = new Joins[Math.max(1, elems.length)];
> > - Union union = store.getSQLFactory().newUnion
> > - (Math.max(1, elems.length));
> > - union.select(new Union.Selector() {
> > - public void select(Select sel, int idx) {
> > - ClassMapping elem = (elems.length == 0) ? null :
> > elems[idx];
> > - resJoins[idx] = selectAll(sel, elem, sm, store, fetch,
> > - JDBCFetchConfiguration.EAGER_PARALLEL);
> > + List parmList = null;
> > + Union union = null;
> > + SelectImpl sel = null;
> > + Map<JDBCStoreManager.SelectKey, Object[]>
> > storeCollectionUnionCache = null;
> > + JDBCStoreManager.SelectKey selKey = null;
> > + if (!((JDBCStoreManager)store).isQuerySQLCacheOn())
> > + union = newUnion(sm, store, fetch, elems, resJoins);
> > + else {
> > + parmList = new ArrayList();
> > + JDBCFetchConfiguration fetchClone = new
> > JDBCFetchConfigurationImpl();
> > + fetchClone.copy(fetch);
> > +
> > + // to specify the type so that no cast is needed
> > + storeCollectionUnionCache = ((JDBCStoreManager)store).
> > +
> > getCacheMapFromQuerySQLCache(StoreCollectionFieldStrategy.class);
> > + selKey =
> > + new JDBCStoreManager.SelectKey(null, field,
> > fetchClone);
> > + Object[] objs = storeCollectionUnionCache.get(selKey);
> > + if (objs != null) {
> > + union = (Union) objs[0];
> > + resJoins[0] = (Joins) objs[1];
> > }
> > - });
> > + else {
> > + synchronized(storeCollectionUnionCache) {
> > + objs = storeCollectionUnionCache.get(selKey);
> > + if (objs == null) {
> > + // select data for this sm
> > + union = newUnion(sm, store, fetch, elems,
> > resJoins);
> > + found = false;
> > + } else {
> > + union = (Union) objs[0];
> > + resJoins[0] = (Joins) objs[1];
> > + }
> > +
> > + sel =
> > ((LogicalUnion.UnionSelect)union.getSelects()[0]).
> > + getDelegate();
> > + if (sel.getSQL() == null) {
> > + ((SelectImpl)sel).setSQL(store, fetch);
> > + found = false;
> > + }
> > +
> > + // only cache the union when elems length is 1 for
> > now
> > + if (!found && elems.length == 1) {
> > + Object[] objs1 = new Object[2];
> > + objs1[0] = union;
> > + objs1[1] = resJoins[0];
> > + ((JDBCStoreManager)store).addToSqlCache(
> > + storeCollectionUnionCache, selKey, objs1);
> > + }
> > + }
> > + }
> > +
> > + 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()));
> > + }
> > +
> > + 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);
> > + }
> > +
> > // create proxy
> > Object coll;
> > ChangeTracker ct = null;
> > @@ -470,14 +545,14 @@
> > }
> >
> > // load values
> > - Result res = union.execute(store, fetch);
> > + Result res = union.execute(store, fetch, parmList);
> > try {
> > int seq = -1;
> > while (res.next()) {
> > if (ct != null && field.getOrderColumn() != null)
> > seq = res.getInt(field.getOrderColumn());
> > - add(store, coll, loadElement(sm, store, fetch, res,
> > - resJoins[res.indexOf()]));
> > + add(store, coll, loadElement(sm, store, fetch,
> > res,
> > + resJoins[res.indexOf()]));
> > }
> > if (ct != null && field.getOrderColumn() != null)
> > ct.setNextSequence(seq + 1);
> > @@ -493,6 +568,21 @@
> > sm.storeObject(field.getIndex(), coll);
> > }
> >
> > + protected Union newUnion(final OpenJPAStateManager sm, final
> > JDBCStore store,
> > + final JDBCFetchConfiguration fetch, final ClassMapping[] elems,
> > + final Joins[] resJoins) {
> > + Union union = store.getSQLFactory().newUnion
> > + (Math.max(1, elems.length));
> > + union.select(new Union.Selector() {
> > + public void select(Select sel, int idx) {
> > + ClassMapping elem = (elems.length == 0) ? null :
> > elems[idx];
> > + resJoins[idx] = selectAll(sel, elem, sm, store, fetch,
> > + JDBCFetchConfiguration.EAGER_PARALLEL);
> > + }
> > + });
> > + return union;
> > + }
> > +
> > /**
> > * Select data for loading, starting in field table.
> > */
> >
> > 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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -202,20 +202,32 @@
> > }
> >
> > 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());
> > + return execute(store, fetch, fetch.getReadLockLevel(), params);
> > }
> >
> > public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
> > - int lockLevel)
> > + int lockLevel, List params)
> > throws SQLException {
> > if (fetch == null)
> > fetch = store.getFetchConfiguration();
> >
> > if (sels.length == 1) {
> > - Result res = sels[0].execute(store, fetch, lockLevel);
> > + Result res = sels[0].execute(store, fetch, lockLevel,
> > params);
> > ((AbstractResult) res).setBaseMapping(mappings[0]);
> > return res;
> > }
> > @@ -224,7 +236,7 @@
> > AbstractResult res;
> > for (int i = 0; i < sels.length; i++) {
> > res = (AbstractResult) sels[i].execute(store, fetch,
> > - lockLevel);
> > + lockLevel, params);
> > res.setBaseMapping(mappings[i]);
> > res.setIndexOf(i);
> >
> > @@ -256,7 +268,7 @@
> > List l;
> > for (int i = 0; i < res.length; i++) {
> > res[i] = (AbstractResult) sels[i].execute(store, fetch,
> > - lockLevel);
> > + lockLevel, params);
> > res[i].setBaseMapping(mappings[i]);
> > res[i].setIndexOf(i);
> >
> > @@ -303,7 +315,7 @@
> > /**
> > * A select that is part of a logical union.
> > */
> > - protected class UnionSelect
> > + public class UnionSelect
> > implements Select {
> >
> > protected final SelectImpl sel;
> > @@ -396,6 +408,18 @@
> > 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);
> > @@ -406,7 +430,7 @@
> > throws SQLException {
> > return sel.execute(store, fetch, lockLevel);
> > }
> > -
> > +
> > public List getSubselects() {
> > return Collections.EMPTY_LIST;
> > }
> > @@ -475,6 +499,14 @@
> > 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();
> > }
> > @@ -717,6 +749,15 @@
> > 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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -450,9 +450,19 @@
> > * 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, null, rsType, rsConcur);
> > + return prepareStatement(conn, rsType, rsConcur, null);
> > }
> >
> > /**
> > @@ -462,6 +472,16 @@
> > 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)
> > @@ -476,7 +496,7 @@
> > else
> > stmnt = conn.prepareStatement(getSQL(), rsType, rsConcur);
> > try {
> > - setParameters(stmnt);
> > + setParameters(stmnt, parms);
> > if (fetch != null) {
> > if (fetch.getFetchBatchSize() > 0)
> > stmnt.setFetchSize(fetch.getFetchBatchSize());
> > @@ -559,13 +579,25 @@
> > */
> > public void setParameters(PreparedStatement ps)
> > throws SQLException {
> > - if (_params == null)
> > + 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)
> > 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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -193,6 +193,19 @@
> > 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}.
> > @@ -515,6 +528,19 @@
> > */
> > 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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -19,6 +19,7 @@
> > 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;
> > @@ -133,6 +134,20 @@
> > * 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)
> > + throws SQLException;
> > +
> > + /**
> > + * Execute this select in the context of the given store manager.
> > + */
> > + public Result execute(JDBCStore store, JDBCFetchConfiguration
> > fetch,
> > int lockLevel)
> > throws SQLException;
> > }
> >
> > 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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -118,6 +118,9 @@
> > // 'parent.address.street' for the purposes of comparisons
> > private Map _aliases = null;
> >
> > + // to cache table alias using Table as the key
> > + private Map _tableAliases = null;
> > +
> > // map of indexes to table aliases like 'TABLENAME t0'
> > private SortedMap _tables = null;
> >
> > @@ -167,7 +170,10 @@
> > // 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.
> > */
> > @@ -300,7 +306,7 @@
> > stmnt = prepareStatement(conn, sql, null,
> > ResultSet.TYPE_FORWARD_ONLY,
> > ResultSet.CONCUR_READ_ONLY, false);
> > - rs = executeQuery(conn, stmnt, sql, false, store);
> > + rs = executeQuery(conn, stmnt, sql, false, store, null);
> > return getCount(rs);
> > } finally {
> > if (rs != null)
> > @@ -312,20 +318,31 @@
> > }
> > }
> >
> > - public Result execute(JDBCStore store, JDBCFetchConfiguration
> > fetch)
> > - throws SQLException {
> > + public Result execute(JDBCStore store, JDBCFetchConfiguration
> > fetch,
> > + List parms) throws SQLException {
> > if (fetch == null)
> > fetch = store.getFetchConfiguration();
> > return execute(store.getContext(), store, fetch,
> > - fetch.getReadLockLevel());
> > + 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);
> > }
> >
> > public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
> > int lockLevel)
> > throws SQLException {
> > - if (fetch == null)
> > - fetch = store.getFetchConfiguration();
> > - return execute(store.getContext(), store, fetch, lockLevel);
> > + return execute(store, fetch, lockLevel, null);
> > }
> >
> > /**
> > @@ -333,16 +350,21 @@
> > * context is passed in separately for profiling purposes.
> > */
> > protected Result execute(StoreContext ctx, JDBCStore store,
> > - JDBCFetchConfiguration fetch, int lockLevel)
> > + JDBCFetchConfiguration fetch, int lockLevel, List params)
> > throws SQLException {
> > - 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 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 isLRS = isLRS();
> > int rsType = (isLRS && supportsRandomAccess(forUpdate))
> > ? -1 : ResultSet.TYPE_FORWARD_ONLY;
> > @@ -351,13 +373,15 @@
> > ResultSet rs = null;
> > try {
> > if (isLRS)
> > - stmnt = prepareStatement(conn, sql, fetch, rsType, -1,
> > true);
> > + stmnt = prepareStatement(conn, _sql, fetch, rsType, -1,
> > true,
> > + params);
> > else
> > - stmnt = prepareStatement(conn, sql, null, rsType, -1,
> > false);
> > + stmnt = prepareStatement(conn, _sql, null, rsType, -1,
> > false,
> > + params);
> >
> > setTimeout(stmnt, forUpdate, fetch);
> >
> > - rs = executeQuery(conn, stmnt, sql, isLRS, store);
> > + rs = executeQuery(conn, stmnt, _sql, isLRS, store, params);
> > } catch (SQLException se) {
> > // clean up statement
> > if (stmnt != null)
> > @@ -367,7 +391,17 @@
> > }
> >
> > return getEagerResult(conn, stmnt, rs, store, fetch, forUpdate,
> > - sql.getSQL());
> > + _sql.getSQL());
> > + }
> > +
> > + 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;
> > }
> >
> > /**
> > @@ -413,10 +447,22 @@
> > 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);
> > + return sql.prepareStatement(conn, rsType, rsConcur,
> > params);
> > else
> > - return sql.prepareStatement(conn, fetch, rsType, -1);
> > + return sql.prepareStatement(conn, fetch, rsType, -1,
> > params);
> > }
> >
> > /**
> > @@ -445,7 +491,8 @@
> > * implementation of executing query.
> > */
> > protected ResultSet executeQuery(Connection conn, PreparedStatement
> > stmnt,
> > - SQLBuffer sql, boolean isLRS, JDBCStore store) throws
> > SQLException {
> > + SQLBuffer sql, boolean isLRS, JDBCStore store, List params)
> > + throws SQLException {
> > return stmnt.executeQuery();
> > }
> >
> > @@ -589,6 +636,19 @@
> > 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;
> > @@ -656,13 +716,30 @@
> > * Return the alias for the given column.
> > */
> > private String getColumnAlias(String col, Table table, PathJoins pj)
> > {
> > + String tableAlias = null;
> > + if (pj == null || pj.path() == null) {
> > + if (_tableAliases == null)
> > + _tableAliases = new HashMap();
> > + tableAlias = (String) _tableAliases.get(table);
> > + if (tableAlias == null) {
> > + tableAlias = getTableAlias(table, pj).toString();
> > + _tableAliases.put(table, tableAlias);
> > + }
> > + return new
> > StringBuilder(tableAlias).append(col).toString();
> > + }
> > + return getTableAlias(table, pj).append(col).toString();
> > + }
> > +
> > + private StringBuilder getTableAlias(Table table, PathJoins pj) {
> > + StringBuilder buf = new StringBuilder();
> > if (_from != null) {
> > String alias = toAlias(_from.getTableIndex(table, pj, true));
> > if (_dict.requiresAliasForSubselect)
> > - return FROM_SELECT_ALIAS + "." + alias + "_" + col;
> > - return alias + "_" + col;
> > + return
> > buf.append(FROM_SELECT_ALIAS).append(".").append(alias).
> > + append("_");
> > + return buf.append(alias).append("_");
> > }
> > - return toAlias(getTableIndex(table, pj, true)) + "." + col;
> > + return buf.append(toAlias(getTableIndex(table, pj,
> > true))).append(".");
> > }
> >
> > public boolean isAggregate() {
> > @@ -1263,12 +1340,38 @@
> > 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;
> > @@ -1281,8 +1384,13 @@
> > 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));
> > @@ -1292,24 +1400,9 @@
> > buf.append(" = ");
> > buf.appendValue(val, fromCols[i]);
> > }
> > -
> > - 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);
> > + return count;
> > }
> > -
> > +
> > /**
> > * Test to see if the given set of columns contains all the
> > * columns in the given potential subset.
> >
> > 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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -113,4 +113,5 @@
> > 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}
> >
> > 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=652913&r1=652912&r2=652913&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 May 2 14:09:14 2008
> > @@ -134,3 +134,5 @@
> > 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}
> >
> > Modified:
> > openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java
> > URL:
> > http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java?rev=652913&r1=652912&r2=652913&view=diff
> >
> > ============================================================================
>
> ...
>
> [Message clipped]