Moved Kodo query compilation cache into OpenJPA.

git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@472218 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Patrick Linskey 2006-11-07 19:33:43 +00:00
parent 92343313fb
commit eb777be3ac
9 changed files with 442 additions and 140 deletions

View File

@ -16,6 +16,7 @@
package org.apache.openjpa.conf;
import java.util.Collection;
import java.util.Map;
import org.apache.openjpa.datacache.DataCache;
import org.apache.openjpa.datacache.DataCacheManager;
@ -1355,6 +1356,27 @@ public interface OpenJPAConfiguration
* Backwards compatibility options.
*/
public Compatibility getCompatibilityInstance ();
/**
* Configuration settings for the query compilation cache to use.
* @see QueryCompilationCacheValue
* @since 0.9.6
*/
public String getQueryCompilationCache();
/**
* Configuration settings for the query compilation cache to use.
* @see QueryCompilationCacheValue
* @since 0.9.6
*/
public void setQueryCompilationCache(String conf);
/**
* Configuration settings for the query compilation cache to use.
* @see QueryCompilationCacheValue
* @since 0.9.6
*/
public Map getQueryCompilationCacheInstance();
/**
* Return the {@link StoreFacadeTypeRegistry} instance associated with this

View File

@ -17,6 +17,8 @@ package org.apache.openjpa.conf;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.datacache.ConcurrentDataCache;
import org.apache.openjpa.datacache.ConcurrentQueryCache;
@ -59,8 +61,8 @@ public class OpenJPAConfigurationImpl
extends ConfigurationImpl
implements OpenJPAConfiguration {
private static final Localizer _loc = Localizer.forPackage
(OpenJPAConfigurationImpl.class);
private static final Localizer _loc =
Localizer.forPackage(OpenJPAConfigurationImpl.class);
// cached state; some of this is created in getter methods, so make
// protected in case subclasses want to access without creating
@ -124,6 +126,7 @@ public class OpenJPAConfigurationImpl
public ObjectValue savepointManagerPlugin;
public ObjectValue orphanedKeyPlugin;
public ObjectValue compatibilityPlugin;
public QueryCompilationCacheValue queryCompilationCachePlugin;
// custom values
public BrokerFactoryValue brokerFactoryPlugin;
@ -162,11 +165,11 @@ public class OpenJPAConfigurationImpl
String[] aliases;
classResolverPlugin = addPlugin("ClassResolver", true);
aliases = new String[]{
"default", "org.apache.openjpa.util.ClassResolverImpl",
// deprecated alias
"spec", "org.apache.openjpa.util.ClassResolverImpl",
};
aliases =
new String[] { "default",
"org.apache.openjpa.util.ClassResolverImpl",
// deprecated alias
"spec", "org.apache.openjpa.util.ClassResolverImpl", };
classResolverPlugin.setAliases(aliases);
classResolverPlugin.setDefault(aliases[0]);
classResolverPlugin.setString(aliases[0]);
@ -176,26 +179,24 @@ public class OpenJPAConfigurationImpl
addValue(brokerFactoryPlugin);
brokerPlugin = addPlugin("BrokerImpl", false);
aliases = new String[]{ "default", BrokerImpl.class.getName() };
aliases = new String[] { "default", BrokerImpl.class.getName() };
brokerPlugin.setAliases(aliases);
brokerPlugin.setDefault(aliases[0]);
brokerPlugin.setString(aliases[0]);
dataCacheManagerPlugin = addPlugin("DataCacheManager", true);
aliases = new String[]{
"default", DataCacheManagerImpl.class.getName(),
};
aliases =
new String[] { "default", DataCacheManagerImpl.class.getName(), };
dataCacheManagerPlugin.setAliases(aliases);
dataCacheManagerPlugin.setDefault(aliases[0]);
dataCacheManagerPlugin.setString(aliases[0]);
dataCacheManagerPlugin.setInstantiatingGetter("getDataCacheManager");
dataCachePlugin = addPlugin("DataCache", false);
aliases = new String[]{
"false", null,
"true", ConcurrentDataCache.class.getName(),
"concurrent", ConcurrentDataCache.class.getName(),
};
aliases =
new String[] { "false", null, "true",
ConcurrentDataCache.class.getName(), "concurrent",
ConcurrentDataCache.class.getName(), };
dataCachePlugin.setAliases(aliases);
dataCachePlugin.setDefault(aliases[0]);
dataCachePlugin.setString(aliases[0]);
@ -205,11 +206,10 @@ public class OpenJPAConfigurationImpl
dataCacheTimeout.set(-1);
queryCachePlugin = addPlugin("QueryCache", true);
aliases = new String[]{
"true", ConcurrentQueryCache.class.getName(),
"concurrent", ConcurrentQueryCache.class.getName(),
"false", null,
};
aliases =
new String[] { "true", ConcurrentQueryCache.class.getName(),
"concurrent", ConcurrentQueryCache.class.getName(), "false",
null, };
queryCachePlugin.setAliases(aliases);
queryCachePlugin.setDefault(aliases[0]);
queryCachePlugin.setString(aliases[0]);
@ -219,71 +219,67 @@ public class OpenJPAConfigurationImpl
dynamicDataStructs.set(false);
lockManagerPlugin = addPlugin("LockManager", false);
aliases = new String[]{
"none", "org.apache.openjpa.kernel.NoneLockManager",
"version", "org.apache.openjpa.kernel.VersionLockManager",
};
aliases =
new String[] { "none", "org.apache.openjpa.kernel.NoneLockManager",
"version", "org.apache.openjpa.kernel.VersionLockManager", };
lockManagerPlugin.setAliases(aliases);
lockManagerPlugin.setDefault(aliases[0]);
lockManagerPlugin.setString(aliases[0]);
inverseManagerPlugin = addPlugin("InverseManager", false);
aliases = new String[]{
"false", null,
"true", "org.apache.openjpa.kernel.InverseManager",
};
aliases =
new String[] { "false", null, "true",
"org.apache.openjpa.kernel.InverseManager", };
inverseManagerPlugin.setAliases(aliases);
inverseManagerPlugin.setDefault(aliases[0]);
inverseManagerPlugin.setString(aliases[0]);
savepointManagerPlugin = addPlugin("SavepointManager", true);
aliases = new String[]{
"in-mem", "org.apache.openjpa.kernel.InMemorySavepointManager",
};
aliases =
new String[] { "in-mem",
"org.apache.openjpa.kernel.InMemorySavepointManager", };
savepointManagerPlugin.setAliases(aliases);
savepointManagerPlugin.setDefault(aliases[0]);
savepointManagerPlugin.setString(aliases[0]);
savepointManagerPlugin.setInstantiatingGetter
("getSavepointManagerInstance");
savepointManagerPlugin
.setInstantiatingGetter("getSavepointManagerInstance");
orphanedKeyPlugin = addPlugin("OrphanedKeyAction", true);
aliases = new String[]{
"log", "org.apache.openjpa.event.LogOrphanedKeyAction",
"exception", "org.apache.openjpa.event.ExceptionOrphanedKeyAction",
"none", "org.apache.openjpa.event.NoneOrphanedKeyAction",
};
aliases =
new String[] { "log",
"org.apache.openjpa.event.LogOrphanedKeyAction", "exception",
"org.apache.openjpa.event.ExceptionOrphanedKeyAction", "none",
"org.apache.openjpa.event.NoneOrphanedKeyAction", };
orphanedKeyPlugin.setAliases(aliases);
orphanedKeyPlugin.setDefault(aliases[0]);
orphanedKeyPlugin.setString(aliases[0]);
orphanedKeyPlugin.setInstantiatingGetter
("getOrphanedKeyActionInstance");
orphanedKeyPlugin
.setInstantiatingGetter("getOrphanedKeyActionInstance");
remoteProviderPlugin = new RemoteCommitProviderValue();
addValue(remoteProviderPlugin);
transactionMode = addBoolean("TransactionMode");
aliases = new String[]{
"local", "false",
"managed", "true",
};
aliases = new String[] { "local", "false", "managed", "true", };
transactionMode.setAliases(aliases);
transactionMode.setDefault(aliases[0]);
managedRuntimePlugin = addPlugin("ManagedRuntime", true);
aliases = new String[]{
"auto", "org.apache.openjpa.ee.AutomaticManagedRuntime",
"jndi", "org.apache.openjpa.ee.JNDIManagedRuntime",
"invocation", "org.apache.openjpa.ee.InvocationManagedRuntime",
};
aliases =
new String[] { "auto",
"org.apache.openjpa.ee.AutomaticManagedRuntime", "jndi",
"org.apache.openjpa.ee.JNDIManagedRuntime", "invocation",
"org.apache.openjpa.ee.InvocationManagedRuntime", };
managedRuntimePlugin.setAliases(aliases);
managedRuntimePlugin.setDefault(aliases[0]);
managedRuntimePlugin.setString(aliases[0]);
managedRuntimePlugin.setInstantiatingGetter
("getManagedRuntimeInstance");
managedRuntimePlugin
.setInstantiatingGetter("getManagedRuntimeInstance");
proxyManagerPlugin = addPlugin("ProxyManager", true);
aliases = new String[]{ "default",
"org.apache.openjpa.util.ProxyManagerImpl" };
aliases =
new String[] { "default",
"org.apache.openjpa.util.ProxyManagerImpl" };
proxyManagerPlugin.setAliases(aliases);
proxyManagerPlugin.setDefault(aliases[0]);
proxyManagerPlugin.setString(aliases[0]);
@ -293,8 +289,9 @@ public class OpenJPAConfigurationImpl
metaFactoryPlugin = addPlugin("MetaDataFactory", false);
metaRepositoryPlugin = addPlugin("MetaDataRepository", false);
aliases = new String[]{ "default",
"org.apache.openjpa.meta.MetaDataRepository" };
aliases =
new String[] { "default",
"org.apache.openjpa.meta.MetaDataRepository" };
metaRepositoryPlugin.setAliases(aliases);
metaRepositoryPlugin.setDefault(aliases[0]);
metaRepositoryPlugin.setString(aliases[0]);
@ -317,15 +314,12 @@ public class OpenJPAConfigurationImpl
connection2URL = addString("Connection2URL");
connection2DriverName = addString("Connection2DriverName");
connection2Properties = addString("Connection2Properties");
connectionFactory2Properties = addString(
"ConnectionFactory2Properties");
connectionFactory2Properties =
addString("ConnectionFactory2Properties");
connectionFactory2Name = addString("ConnectionFactory2Name");
connectionFactoryMode = addBoolean("ConnectionFactoryMode");
aliases = new String[]{
"local", "false",
"managed", "true",
};
aliases = new String[] { "local", "false", "managed", "true", };
connectionFactoryMode.setAliases(aliases);
connectionFactoryMode.setDefault(aliases[0]);
@ -334,10 +328,10 @@ public class OpenJPAConfigurationImpl
optimistic.set(true);
autoClear = addInt("AutoClear");
aliases = new String[]{
"datastore", String.valueOf(AutoClear.CLEAR_DATASTORE),
"all", String.valueOf(AutoClear.CLEAR_ALL),
};
aliases =
new String[] { "datastore",
String.valueOf(AutoClear.CLEAR_DATASTORE), "all",
String.valueOf(AutoClear.CLEAR_ALL), };
autoClear.setAliases(aliases);
autoClear.setDefault(aliases[0]);
autoClear.set(AutoClear.CLEAR_DATASTORE);
@ -348,14 +342,13 @@ public class OpenJPAConfigurationImpl
retainState.set(true);
restoreState = addInt("RestoreState");
aliases = new String[]{
"none", String.valueOf(RestoreState.RESTORE_NONE),
"false", String.valueOf(RestoreState.RESTORE_NONE),
"immutable", String.valueOf(RestoreState.RESTORE_IMMUTABLE),
// "true" for compat with jdo RestoreValues
"true", String.valueOf(RestoreState.RESTORE_IMMUTABLE),
"all", String.valueOf(RestoreState.RESTORE_ALL),
};
aliases =
new String[] { "none", String.valueOf(RestoreState.RESTORE_NONE),
"false", String.valueOf(RestoreState.RESTORE_NONE),
"immutable", String.valueOf(RestoreState.RESTORE_IMMUTABLE),
// "true" for compat with jdo RestoreValues
"true", String.valueOf(RestoreState.RESTORE_IMMUTABLE), "all",
String.valueOf(RestoreState.RESTORE_ALL), };
restoreState.setAliases(aliases);
restoreState.setDefault(aliases[0]);
restoreState.set(RestoreState.RESTORE_IMMUTABLE);
@ -365,11 +358,10 @@ public class OpenJPAConfigurationImpl
addValue(autoDetach);
detachStatePlugin = addPlugin("DetachState", true);
aliases = new String[]{
"loaded", DetachOptions.Loaded.class.getName(),
"fgs", DetachOptions.FetchGroups.class.getName(),
"all", DetachOptions.All.class.getName(),
};
aliases =
new String[] { "loaded", DetachOptions.Loaded.class.getName(),
"fgs", DetachOptions.FetchGroups.class.getName(), "all",
DetachOptions.All.class.getName(), };
detachStatePlugin.setAliases(aliases);
detachStatePlugin.setDefault(aliases[0]);
detachStatePlugin.setString(aliases[0]);
@ -394,15 +386,14 @@ public class OpenJPAConfigurationImpl
fetchGroups = addStringList("FetchGroups");
fetchGroups.setDefault("default");
fetchGroups.set(new String[]{ "default" });
fetchGroups.set(new String[] { "default" });
flushBeforeQueries = addInt("FlushBeforeQueries");
aliases = new String[]{
"true", String.valueOf(QueryFlushModes.FLUSH_TRUE),
"false", String.valueOf(QueryFlushModes.FLUSH_FALSE),
"with-connection", String.valueOf
(QueryFlushModes.FLUSH_WITH_CONNECTION),
};
aliases =
new String[] { "true", String.valueOf(QueryFlushModes.FLUSH_TRUE),
"false", String.valueOf(QueryFlushModes.FLUSH_FALSE),
"with-connection",
String.valueOf(QueryFlushModes.FLUSH_WITH_CONNECTION), };
flushBeforeQueries.setAliases(aliases);
flushBeforeQueries.setDefault(aliases[0]);
flushBeforeQueries.set(QueryFlushModes.FLUSH_TRUE);
@ -413,22 +404,20 @@ public class OpenJPAConfigurationImpl
lockTimeout.set(-1);
readLockLevel = addInt("ReadLockLevel");
aliases = new String[]{
"read", String.valueOf(LockLevels.LOCK_READ),
"write", String.valueOf(LockLevels.LOCK_WRITE),
"none", String.valueOf(LockLevels.LOCK_NONE),
};
aliases =
new String[] { "read", String.valueOf(LockLevels.LOCK_READ),
"write", String.valueOf(LockLevels.LOCK_WRITE), "none",
String.valueOf(LockLevels.LOCK_NONE), };
readLockLevel.setAliases(aliases);
readLockLevel.setDefault(aliases[0]);
readLockLevel.set(LockLevels.LOCK_READ);
readLockLevel.setAliasListComprehensive(true);
writeLockLevel = addInt("WriteLockLevel");
aliases = new String[]{
"read", String.valueOf(LockLevels.LOCK_READ),
"write", String.valueOf(LockLevels.LOCK_WRITE),
"none", String.valueOf(LockLevels.LOCK_NONE),
};
aliases =
new String[] { "read", String.valueOf(LockLevels.LOCK_READ),
"write", String.valueOf(LockLevels.LOCK_WRITE), "none",
String.valueOf(LockLevels.LOCK_NONE), };
writeLockLevel.setAliases(aliases);
writeLockLevel.setDefault(aliases[1]);
writeLockLevel.set(LockLevels.LOCK_WRITE);
@ -439,38 +428,40 @@ public class OpenJPAConfigurationImpl
addValue(seqPlugin);
connectionRetainMode = addInt("ConnectionRetainMode");
aliases = new String[]{
"on-demand",
String.valueOf(ConnectionRetainModes.CONN_RETAIN_DEMAND),
"transaction",
String.valueOf(ConnectionRetainModes.CONN_RETAIN_TRANS),
"always",
String.valueOf(ConnectionRetainModes.CONN_RETAIN_ALWAYS),
// deprecated
"persistence-manager",
String.valueOf(ConnectionRetainModes.CONN_RETAIN_ALWAYS),
};
aliases =
new String[] { "on-demand",
String.valueOf(ConnectionRetainModes.CONN_RETAIN_DEMAND),
"transaction",
String.valueOf(ConnectionRetainModes.CONN_RETAIN_TRANS),
"always",
String.valueOf(ConnectionRetainModes.CONN_RETAIN_ALWAYS),
// deprecated
"persistence-manager",
String.valueOf(ConnectionRetainModes.CONN_RETAIN_ALWAYS), };
connectionRetainMode.setAliases(aliases);
connectionRetainMode.setDefault(aliases[0]);
connectionRetainMode.setAliasListComprehensive(true);
connectionRetainMode.set(ConnectionRetainModes.CONN_RETAIN_DEMAND);
filterListenerPlugins = addPluginList("FilterListeners");
filterListenerPlugins.setInstantiatingGetter
("getFilterListenerInstances");
filterListenerPlugins
.setInstantiatingGetter("getFilterListenerInstances");
aggregateListenerPlugins = addPluginList("AggregateListeners");
aggregateListenerPlugins.setInstantiatingGetter
("getAggregateListenerInstances");
aggregateListenerPlugins
.setInstantiatingGetter("getAggregateListenerInstances");
retryClassRegistration = addBoolean("RetryClassRegistration");
compatibilityPlugin = addPlugin("Compatibility", true);
aliases = new String[]{ "default", Compatibility.class.getName() };
aliases = new String[] { "default", Compatibility.class.getName() };
compatibilityPlugin.setAliases(aliases);
compatibilityPlugin.setDefault(aliases[0]);
compatibilityPlugin.setString(aliases[0]);
compatibilityPlugin.setInstantiatingGetter("getCompatibilityInstance");
queryCompilationCachePlugin = new QueryCompilationCacheValue(this);
addValue(queryCompilationCachePlugin);
// initialize supported options that some runtimes may not support
supportedOptions.add(OPTION_NONTRANS_READ);
@ -510,8 +501,8 @@ public class OpenJPAConfigurationImpl
if (this.spec != null) {
if (!this.spec.equals(spec)
&& getConfigurationLog().isWarnEnabled())
getConfigurationLog().warn(_loc.get("diff-specs", this.spec,
spec));
getConfigurationLog().warn(
_loc.get("diff-specs", this.spec, spec));
return false;
}
this.spec = spec;
@ -558,8 +549,8 @@ public class OpenJPAConfigurationImpl
}
public BrokerImpl newBrokerInstance(String user, String pass) {
BrokerImpl broker = (BrokerImpl) brokerPlugin.instantiate
(BrokerImpl.class, this);
BrokerImpl broker =
(BrokerImpl) brokerPlugin.instantiate(BrokerImpl.class, this);
if (broker != null)
broker.setAuthentication(user, pass);
return broker;
@ -584,8 +575,9 @@ public class OpenJPAConfigurationImpl
public DataCacheManager getDataCacheManagerInstance() {
DataCacheManager dcm = (DataCacheManager) dataCacheManagerPlugin.get();
if (dcm == null) {
dcm = (DataCacheManager) dataCacheManagerPlugin.instantiate
(DataCacheManager.class, this);
dcm =
(DataCacheManager) dataCacheManagerPlugin.instantiate(
DataCacheManager.class, this);
dcm.initialize(this, dataCachePlugin, queryCachePlugin);
}
return dcm;
@ -662,8 +654,8 @@ public class OpenJPAConfigurationImpl
}
public InverseManager newInverseManagerInstance() {
return (InverseManager) inverseManagerPlugin.instantiate
(InverseManager.class, this);
return (InverseManager) inverseManagerPlugin.instantiate(
InverseManager.class, this);
}
public void setSavepointManager(String savepointManager) {
@ -714,8 +706,8 @@ public class OpenJPAConfigurationImpl
return remoteProviderPlugin.instantiateProvider(this);
}
public void setRemoteCommitEventManager
(RemoteCommitEventManager remoteEventManager) {
public void setRemoteCommitEventManager(
RemoteCommitEventManager remoteEventManager) {
assertNotReadOnly();
this.remoteEventManager = remoteEventManager;
remoteProviderPlugin.configureEventManager(remoteEventManager);
@ -806,8 +798,8 @@ public class OpenJPAConfigurationImpl
}
public MetaDataFactory newMetaDataFactoryInstance() {
return (MetaDataFactory) metaFactoryPlugin.instantiate
(MetaDataFactory.class, this);
return (MetaDataFactory) metaFactoryPlugin.instantiate(
MetaDataFactory.class, this);
}
public void setMetaDataRepository(String meta) {
@ -831,8 +823,8 @@ public class OpenJPAConfigurationImpl
}
public MetaDataRepository newMetaDataRepositoryInstance() {
return (MetaDataRepository) metaRepositoryPlugin.instantiate
(MetaDataRepository.class, this);
return (MetaDataRepository) metaRepositoryPlugin.instantiate(
MetaDataRepository.class, this);
}
public void setConnectionUserName(String connectionUserName) {
@ -880,8 +872,8 @@ public class OpenJPAConfigurationImpl
return connectionProperties.getString();
}
public void setConnectionFactoryProperties
(String connectionFactoryProperties) {
public void setConnectionFactoryProperties(
String connectionFactoryProperties) {
assertNotReadOnly();
this.connectionFactoryProperties.setString(connectionFactoryProperties);
}
@ -924,8 +916,8 @@ public class OpenJPAConfigurationImpl
public Object getConnectionFactory() {
if (connectionFactory.get() == null)
connectionFactory.set(lookupConnectionFactory
(getConnectionFactoryName()), true);
connectionFactory.set(
lookupConnectionFactory(getConnectionFactoryName()), true);
return connectionFactory.get();
}
@ -984,11 +976,11 @@ public class OpenJPAConfigurationImpl
return connection2Properties.getString();
}
public void setConnectionFactory2Properties
(String connectionFactory2Properties) {
public void setConnectionFactory2Properties(
String connectionFactory2Properties) {
assertNotReadOnly();
this.connectionFactory2Properties.setString
(connectionFactory2Properties);
this.connectionFactory2Properties
.setString(connectionFactory2Properties);
}
public String getConnectionFactory2Properties() {
@ -1011,8 +1003,8 @@ public class OpenJPAConfigurationImpl
public Object getConnectionFactory2() {
if (connectionFactory2.get() == null)
connectionFactory2.set(lookupConnectionFactory
(getConnectionFactory2Name()), false);
connectionFactory2.set(
lookupConnectionFactory(getConnectionFactory2Name()), false);
return connectionFactory2.get();
}
@ -1392,6 +1384,21 @@ public class OpenJPAConfigurationImpl
return (Compatibility) compatibilityPlugin.get();
}
public String getQueryCompilationCache() {
return queryCompilationCachePlugin.getString();
}
public void setQueryCompilationCache(String conf) {
queryCompilationCachePlugin.setString(conf);
}
public Map getQueryCompilationCacheInstance() {
if (queryCompilationCachePlugin.get() == null)
queryCompilationCachePlugin.instantiate(
QueryCompilationCacheValue.class, this);
return (Map) queryCompilationCachePlugin.get();
}
public StoreFacadeTypeRegistry getStoreFacadeTypeRegistry() {
return _storeFacadeRegistry;
}
@ -1410,5 +1417,5 @@ public class OpenJPAConfigurationImpl
public Log getConfigurationLog() {
return getLog(LOG_RUNTIME);
}
}
}

View File

@ -0,0 +1,60 @@
package org.apache.openjpa.conf;
import java.util.*;
import org.apache.openjpa.lib.conf.*;
import org.apache.openjpa.lib.util.concurrent.*;
import org.apache.openjpa.util.*;
/**
* <p>A cache of compiled queries.</p>
*
* @author Abe White
* @since 0.9.6 (also existed in prior versions of Kodo)
* @nojavadoc
*/
public class QueryCompilationCacheValue
extends PluginValue {
/**
* Query compilation cache configuration property key.
*/
private static final String KEY = "QueryCompilationCache";
public static final String[] ALIASES = {
"true", CacheMap.class.getName(),
"all", ConcurrentHashMap.class.getName(),
"false", null,
};
private final OpenJPAConfiguration _conf;
public QueryCompilationCacheValue(OpenJPAConfiguration conf) {
super(KEY, true);
setAliases(ALIASES);
setDefault(ALIASES[0]);
setClassName(ALIASES[1]);
setInstantiatingGetter("this.instantiate");
setScope(getClass());
_conf = conf;
}
/**
* Instantiate internal map.
*/
public void instantiate() {
if (get() == null)
instantiate(Map.class, _conf, true);
}
public Object newInstance(String clsName, Class type,
Configuration conf, boolean fatal) {
// make sure map handles concurrency
Map map = (Map) super.newInstance(clsName, type, conf, fatal);
if (map != null && !(map instanceof Hashtable)
&& !(map instanceof CacheMap)
&& !(map instanceof ConcurrentMap))
map = Collections.synchronizedMap(map);
return map;
}
}

View File

@ -15,6 +15,7 @@
*/
package org.apache.openjpa.kernel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -26,6 +27,7 @@ import java.util.ListIterator;
import java.util.Map;
import org.apache.commons.collections.map.LinkedMap;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.enhance.PersistenceCapable;
@ -574,7 +576,7 @@ public class QueryImpl
_readOnly = false;
_compiling = true;
try {
_compiled = newCompilation();
_compiled = compilationFromCache();
return _compiled;
} catch (OpenJPAException ke) {
throw ke;
@ -589,7 +591,38 @@ public class QueryImpl
/**
* Create and initialize a query compilation based on current data.
*/
protected Compilation newCompilation() {
protected Compilation compilationFromCache() {
Map compCache =
_broker.getConfiguration().getQueryCompilationCacheInstance();
if (compCache == null) {
return newCompilation();
} else {
CompilationKey key = new CompilationKey();
key.queryType = _storeQuery.getClass();
key.candidateType = getCandidateType();
key.subclasses = hasSubclasses();
key.query = getQueryString();
key.language = getLanguage();
key.storeKey = _storeQuery.newCompilationKey();
Compilation comp = (Compilation) compCache.get(key);
// parse declarations if needed
boolean cache = false;
if (comp == null) {
comp = newCompilation();
// only cache those queries that can be compiled
cache = comp.storeData != null;
} else
_storeQuery.populateFromCompilation(comp.storeData);
// cache parsed state if needed
if (cache)
compCache.put(key, comp);
return comp;
}
}
private Compilation newCompilation() {
Compilation comp = new Compilation();
comp.storeData = _storeQuery.newCompilation();
_storeQuery.populateFromCompilation(comp.storeData);
@ -2044,4 +2077,52 @@ public class QueryImpl
return _res;
}
}
/**
* Struct to hold the unparsed properties associated with a query.
*/
private static class CompilationKey
implements Serializable {
public Class queryType = null;
public Class candidateType = null;
public boolean subclasses = true;
public String query = null;
public String language = null;
public Object storeKey = null;
public int hashCode() {
int rs = 17;
rs = 37 * rs + ((queryType == null) ? 0 : queryType.hashCode());
rs = 37 * rs + ((query == null) ? 0 : query.hashCode());
rs = 37 * rs + ((language == null) ? 0 : language.hashCode());
rs = 37 * rs + ((storeKey == null) ? 0 : storeKey.hashCode());
return rs;
}
public boolean equals(Object other) {
if (other == this)
return true;
if (other == null || other.getClass() != getClass())
return false;
CompilationKey key = (CompilationKey) other;
if (key.queryType != queryType
|| !StringUtils.equals(key.query, query)
|| !StringUtils.equals(key.language, language))
return false;
if (!ObjectUtils.equals(key.storeKey, storeKey))
return false;
// allow either candidate type to be null because it might be
// encoded in the query string, but if both are set then they
// must be equal
if (candidateType != null && key.candidateType != null)
return candidateType == key.candidateType
&& subclasses == key.subclasses;
return true;
}
}
}

View File

@ -1900,7 +1900,6 @@ public class ClassMetaData
String cap;
int type;
Class c;
ClassMetaData idmeta;
int access = meta.getAccessType();
for (int i = 0; i < fmds.length; i++) {
switch (fmds[i].getDeclaredTypeCode()) {

View File

@ -532,6 +532,17 @@ Compatibility-displayorder: 50
Compatibility-expert: true
Compatibility-interface: org.apache.openjpa.conf.Compatibility
QueryCompilationCache-name: Query compilation cache
QueryCompilationCache-desc: Plugin used to cache query compilation data. \
Must implement java.util.Map. Does not need to be thread-safe -- it will \
be wrapped via the Collections.synchronizedMap() method if it does not \
extend org.apache.openjpa.util.CacheMap.
QueryCompilationCache-type: General
QueryCompilationCache-cat: Cache.Queries
QueryCompilationCache-displayorder: 50
QueryCompilationCache-expert: true
QueryCompilationCache-interface: java.util.Map
no-named-cf: use a DataSource bound to JNDI
diff-specs: Attempt to configure for multiple specifications. Was configured \
for "{0}". Attempt to now configure for "{1}". This attempt will be \

View File

@ -788,4 +788,82 @@ Iterator cachedIterator = extentQuery.getResultList().iterator();
</itemizedlist>
</section>
</section>
<section id="ref_guide_cache_querycomp">
<title>Query Compilation Cache</title>
<indexterm zone="ref_guide_cache_querycomp">
<primary>caching</primary>
<secondary>query compilation cache</secondary>
</indexterm>
<para>
The query compilation cache is a <classname>Map</classname> used to
cache parsed query strings. As a result, most queries are
only parsed once in OpenJPA, and cached thereafter. You can control the
compilation cache through the
<link linkend="openjpa.QueryCompilationCache"><literal>
openjpa.QueryCompilationCache</literal></link> configuration property.
This property accepts a plugin string (see
<xref linkend="ref_guide_conf_plugins"/>) describing the
<classname>Map</classname> used to associate query strings and their
parsed form. This property accepts the following aliases:
</para>
<table>
<title>Pre-defined aliases</title>
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<colspec colname="alias"/>
<colspec colname="value"/>
<colspec colname="notes"/>
<thead>
<row>
<entry colname="alias">Alias</entry>
<entry colname="value">Value</entry>
<entry colname="notes">Notes</entry>
</row>
</thead>
<tbody>
<row>
<entry colname="alias">
<literal>true</literal>
</entry>
<entry colname="value">
<literal>org.apache.openjpa.util.CacheMap</literal>
</entry>
<entry colname="notes">
The default option. Uses a
<ulink url="&javadoc-dir;/org/apache/openjpa/util/CacheMap.html">
<literal>CacheMap</literal></ulink> to store
compilation data. <literal>CacheMap</literal> uses
a least-recently-used strategy for a fixed number
of cache entries, and an optional soft reference
map for entries that are moved out of the LRU
space. So, for applications that have a
monotonically increasing number of distinct queries,
this option can be used to ensure that a fixed
amount of memory is used by the cache.
</entry>
</row>
<row>
<entry colname="alias"><literal>all</literal></entry>
<entry colname="value">
<literal>org.apache.openjpa.lib.util.ConcurrentHashMap</literal>
</entry>
<entry colname="notes">
This is the fastest option, but compilation data is
never dropped from the cache, so if you use a large
number of dynamic queries, this option may result in
ever-increasing memory usage. Note that if your
queries only differ in the values of the parameters,
this should not be an issue.
</entry>
</row>
<row>
<entry colname="alias"><literal>false</literal></entry>
<entry colname="value"><emphasis>none</emphasis></entry>
<entry colname="notes">
Disables the compilation cache.
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
</chapter>

View File

@ -2454,6 +2454,34 @@ implementation to use for caching of queries loaded from the data store. See
<xref linkend="ref_guide_cache_query"/> for details.
</para>
</section>
<section id="openjpa.QueryCompilationCache">
<title>openjpa.QueryCompilationCache</title>
<indexterm zone="openjpa.QueryCompilationCache">
<primary>QueryCompilationCache</primary>
</indexterm>
<indexterm zone="openjpa.QueryCompilationCache">
<primary>caching</primary>
<secondary>QueryCompilationCache</secondary>
</indexterm>
<para>
<emphasis role="bold">Property name:</emphasis>
<literal>openjpa.QueryCompilationCache</literal>
</para>
<para>
<emphasis role="bold">Resource adaptor config-property:</emphasis>
<literal>QueryCompilationCache</literal>
</para>
<para>
<emphasis role="bold">Default:</emphasis> <literal>true</literal>.
</para>
<para>
<emphasis role="bold">Description:</emphasis> A plugin
string (see <xref linkend="ref_guide_conf_plugins"/>)
describing the <literal>java.util.Map</literal> to use for
caching of data used during query compilation.
See <xref linkend="ref_guide_cache_querycomp"/> for details.
</para>
</section>
<section id="openjpa.ReadLockLevel">
<title>
openjpa.ReadLockLevel

View File

@ -489,6 +489,22 @@ fields to be of type <classname>Set, SortedSet, HashSet,</classname> or
<classname>TreeSet</classname>.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">Use query parameters instead of
encoding search data in filter strings</emphasis>
<para><emphasis>performance</emphasis></para>
</entry>
<entry colname="desc">
If your queries depend on parameter data only known at
runtime, you should use query parameters rather than
dynamically building different query strings. OpenJPA
performs aggressive caching of query compilation
data, and the effectiveness of this cache is diminished if
multiple query filters are used where a single one could
have sufficed.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">