You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by cu...@apache.org on 2009/12/08 22:51:27 UTC

svn commit: r888586 - in /openjpa/branches/1.2.x: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-kernel/src/main/java/org/apache/openjpa/conf/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-kernel/src/main/java/org/ap...

Author: curtisr7
Date: Tue Dec  8 21:51:26 2009
New Revision: 888586

URL: http://svn.apache.org/viewvc?rev=888586&view=rev
Log:
OPENJPA-250: Committing to 1.2.x. Submitted by Patrick Linskey, Simon Droscher, and Rick Curtis.

Modified:
    openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
    openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
    openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
    openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
    openjpa/branches/1.2.x/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties
    openjpa/branches/1.2.x/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java
    openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java

Modified: openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java (original)
+++ openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java Tue Dec  8 21:51:26 2009
@@ -143,7 +143,15 @@
     /**
      * Representation of the database schema.
      */
-    public synchronized SchemaGroup getSchemaGroup() {
+    public SchemaGroup getSchemaGroup() {
+        if(_locking){
+            synchronized(this){
+                if (_schema == null)
+                    _schema = ((JDBCConfiguration) getConfiguration()).
+                        getSchemaFactoryInstance().readSchema();
+                return _schema;                
+            }
+        }
         if (_schema == null)
             _schema = ((JDBCConfiguration) getConfiguration()).
                 getSchemaFactoryInstance().readSchema();
@@ -153,33 +161,59 @@
     /**
      * Representation of the database schema.
      */
-    public synchronized void setSchemaGroup(SchemaGroup schema) {
-        _schema = schema;
+    public void setSchemaGroup(SchemaGroup schema) {
+        if (_locking) {
+            synchronized (this) {
+                _schema = schema;
+            }
+        } else {
+            _schema = schema;
+        }
     }
 
     /**
      * Installs mapping strategies on components.
      */
-    public synchronized StrategyInstaller getStrategyInstaller() {
-        if (_installer == null)
-            _installer = new RuntimeStrategyInstaller(this);
-        return _installer;
+    public StrategyInstaller getStrategyInstaller() {
+        if (_locking) {
+            synchronized (this) {
+                if (_installer == null)
+                    _installer = new RuntimeStrategyInstaller(this);
+                return _installer;
+            }
+        } else {
+            if (_installer == null)
+                _installer = new RuntimeStrategyInstaller(this);
+            return _installer;
+        }
     }
 
     /**
      * Installs mapping strategies on components.
      */
-    public synchronized void setStrategyInstaller(StrategyInstaller installer) {
-        _installer = installer;
+    public void setStrategyInstaller(StrategyInstaller installer) {
+        if (_locking) {
+            synchronized (this) {
+                _installer = installer;
+            }
+        } else {
+            _installer = installer;
+        }
     }
 
     /**
      * Return the query result mapping for the given name.
      */
-    public synchronized QueryResultMapping getQueryResultMapping(Class cls,
+    public QueryResultMapping getQueryResultMapping(Class cls,
         String name, ClassLoader envLoader, boolean mustExist) {
-        QueryResultMapping res = getQueryResultMappingInternal(cls, name,
-            envLoader);
+        QueryResultMapping res = null;
+        if (_locking) {
+            synchronized (this) {
+                res = getQueryResultMappingInternal(cls, name, envLoader);
+            }
+        } else {
+            res = getQueryResultMappingInternal(cls, name, envLoader);
+        }
         if (res == null && mustExist)
             throw new MetaDataException(_loc.get("no-query-res", cls, name));
         return res;
@@ -219,26 +253,49 @@
     /**
      * Return all cached query result mappings.
      */
-    public synchronized QueryResultMapping[] getQueryResultMappings() {
-        Collection values = _results.values();
-        return (QueryResultMapping[]) values.toArray
-            (new QueryResultMapping[values.size()]);
+    public QueryResultMapping[] getQueryResultMappings() {
+        if (_locking) {
+            synchronized (this) {
+                Collection values = _results.values();
+                return (QueryResultMapping[]) values.toArray(new QueryResultMapping[values.size()]);
+            }
+        } else {
+            Collection values = _results.values();
+            return (QueryResultMapping[]) values.toArray(new QueryResultMapping[values.size()]);
+        }
     }
 
     /**
      * Return the cached query result mapping with the given name, or null if
      * none.
      */
-    public synchronized QueryResultMapping getCachedQueryResultMapping
+    public QueryResultMapping getCachedQueryResultMapping
         (Class cls, String name) {
-        return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
+        if (_locking) {
+            synchronized (this) {
+                return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
+            }
+        } else {
+            return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
+        }
     }
 
     /**
      * Add a query result mapping.
      */
-    public synchronized QueryResultMapping addQueryResultMapping(Class cls,
+    public QueryResultMapping addQueryResultMapping(Class cls,
         String name) {
+        if (_locking) {
+            return addQueryResultMappingLocking(cls, name);
+        } else {
+            return addQueryResultMappingInternal(cls, name);
+        }
+    }
+    private synchronized QueryResultMapping addQueryResultMappingLocking(Class cls, String name) {
+        return addQueryResultMappingInternal(cls, name);
+    }
+
+    private QueryResultMapping addQueryResultMappingInternal(Class cls, String name) {
         QueryResultMapping res = new QueryResultMapping(name, this);
         res.setDefiningType(cls);
         _results.put(getQueryResultKey(res), res);
@@ -248,19 +305,33 @@
     /**
      * Remove a query result mapping.
      */
-    public synchronized boolean removeQueryResultMapping
+    public boolean removeQueryResultMapping
         (QueryResultMapping res) {
-        return _results.remove(getQueryResultKey(res)) != null;
+        if (_locking) {
+            synchronized (this) {
+                return _results.remove(getQueryResultKey(res)) != null;
+            }
+        } else {
+            return _results.remove(getQueryResultKey(res)) != null;
+        }
     }
 
     /**
      * Remove a query result mapping.
      */
-    public synchronized boolean removeQueryResultMapping(Class cls,
+    public boolean removeQueryResultMapping(Class cls,
         String name) {
-        if (name == null)
-            return false;
-        return _results.remove(getQueryResultKey(cls, name)) != null;
+        if (_locking) {
+            synchronized (this) {
+                if (name == null)
+                    return false;
+                return _results.remove(getQueryResultKey(cls, name)) != null;
+            }
+        } else {
+            if (name == null)
+                return false;
+            return _results.remove(getQueryResultKey(cls, name)) != null;
+        }
     }
 
     /**
@@ -300,10 +371,18 @@
             mustExist);
     }
 
-    public synchronized void clear() {
-        super.clear();
-        _schema = null;
-        _results.clear();
+    public void clear() {
+        if (_locking) {
+            synchronized (this) {
+                super.clear();
+                _schema = null;
+                _results.clear();
+            }
+        } else {
+            super.clear();
+            _schema = null;
+            _results.clear();
+        }
     }
 
     protected void prepareMapping(ClassMetaData meta) {

Modified: openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java (original)
+++ openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java Tue Dec  8 21:51:26 2009
@@ -126,7 +126,7 @@
     public BooleanValue multithreaded;
     public StringValue mapping;
     public PluginValue metaFactoryPlugin;
-    public ObjectValue metaRepositoryPlugin;
+    public MetaDataRepositoryValue metaRepositoryPlugin;
     public ObjectValue lockManagerPlugin;
     public ObjectValue inverseManagerPlugin;
     public ObjectValue savepointManagerPlugin;
@@ -303,7 +303,7 @@
         mapping = addString("Mapping");
         metaFactoryPlugin = addPlugin("MetaDataFactory", false);
 
-        metaRepositoryPlugin = (ObjectValue)
+        metaRepositoryPlugin = (MetaDataRepositoryValue)
             addValue(new MetaDataRepositoryValue());
 
         connectionFactory = addObject("ConnectionFactory");

Modified: openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java (original)
+++ openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java Tue Dec  8 21:51:26 2009
@@ -256,7 +256,7 @@
      * Load the configured persistent classes list. Performed automatically
      * whenever a broker is created.
      */
-    private void loadPersistentTypes(ClassLoader envLoader) {
+    public void loadPersistentTypes(ClassLoader envLoader) {
         // if we've loaded the persistent types and the class name list
         // is empty, then we can simply return. Note that there is a
         // potential threading scenario in which _persistentTypesLoaded is

Modified: openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java (original)
+++ openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java Tue Dec  8 21:51:26 2009
@@ -20,6 +20,7 @@
 
 import java.io.Serializable;
 import java.security.AccessController;
+import java.security.PrivilegedActionException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -37,8 +38,8 @@
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.enhance.DynamicPersistenceCapable;
 import org.apache.openjpa.enhance.PCRegistry;
-import org.apache.openjpa.enhance.PCRegistry.RegisterClassListener;
 import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.PCRegistry.RegisterClassListener;
 import org.apache.openjpa.event.LifecycleEventManager;
 import org.apache.openjpa.lib.conf.Configurable;
 import org.apache.openjpa.lib.conf.Configuration;
@@ -46,11 +47,14 @@
 import org.apache.openjpa.lib.util.Closeable;
 import org.apache.openjpa.lib.util.J2DoPrivHelper;
 import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.MultiClassLoader;
+import org.apache.openjpa.lib.util.Options;
 import org.apache.openjpa.lib.util.StringDistance;
 import org.apache.openjpa.util.ImplHelper;
 import org.apache.openjpa.util.InternalException;
 import org.apache.openjpa.util.MetaDataException;
 import org.apache.openjpa.util.OpenJPAId;
+
 import serp.util.Strings;
 
 /**
@@ -63,6 +67,8 @@
 public class MetaDataRepository
     implements PCRegistry.RegisterClassListener, Configurable, Closeable, 
     MetaDataModes, Serializable {
+    
+    protected boolean _locking = true;
 
     /**
      * Constant to not validate any metadata.
@@ -105,18 +111,18 @@
 
     // cache of parsed metadata, oid class to class, and interface class
     // to metadatas
-    private final Map _metas = new HashMap();
-    private final Map _oids = Collections.synchronizedMap(new HashMap());
-    private final Map _impls = Collections.synchronizedMap(new HashMap());
-    private final Map _ifaces = Collections.synchronizedMap(new HashMap());
-    private final Map _queries = new HashMap();
-    private final Map _seqs = new HashMap();
-    private final Map _aliases = Collections.synchronizedMap(new HashMap());
-    private final Map _pawares = Collections.synchronizedMap(new HashMap());
-    private final Map _nonMapped = Collections.synchronizedMap(new HashMap());
+	private Map _metas = new HashMap();
+	private Map _oids = Collections.synchronizedMap(new HashMap());
+	private Map _impls = Collections.synchronizedMap(new HashMap());
+	private Map _ifaces = Collections.synchronizedMap(new HashMap());
+	private Map _queries = new HashMap();
+	private Map _seqs = new HashMap();
+	private Map _aliases = Collections.synchronizedMap(new HashMap());
+	private Map _pawares = Collections.synchronizedMap(new HashMap());
+	private Map _nonMapped = Collections.synchronizedMap(new HashMap());
     
     // map of classes to lists of their subclasses
-    private final Map _subs = Collections.synchronizedMap(new HashMap());
+	private Map _subs = Collections.synchronizedMap(new HashMap());
 
     // xml mapping
     protected final XMLMetaData[] EMPTY_XMLMETAS;
@@ -147,6 +153,9 @@
         new LifecycleEventManager.ListenerList(3);
 
     private boolean _reorderMetaDataResolution = false;
+    protected boolean _preload = false;
+    protected boolean _preloadComplete = false;
+    private static final String PRELOAD_STR = "Preload";
     
     /**
      * Default constructor.  Configure via {@link Configurable}.
@@ -275,6 +284,70 @@
     }
 
     /**
+     * Sets whether this repository will load all MetaData for all known persistent classes at
+     * initialization and remove all locking. Defaults to false.
+     */
+    public void setPreload(boolean p) {
+        _preload = p;
+    }
+
+    /**
+     * Returns a boolean indicating whether this repository will load all MetaData for all known
+     * persistent classes at initialization.
+     */
+    public boolean getPreload() {
+        return _preload;
+    }   
+    
+     /**
+     * If the openjpa.MetaDataRepository plugin value Preload=true is set, this method will load all
+     * MetaData for all persistent classes and will remove locking from this class.
+     * <p>
+     * 
+     */
+    public synchronized void preload() {
+        if (_preload == false) {
+            return;
+        }
+        // If pooling EMFs, this method may be invoked more than once. Only perform this work once.
+        if (_preloadComplete == true) {
+            return;
+        }
+
+        MultiClassLoader multi = AccessController.doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction());
+        multi.addClassLoader(AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()));
+        multi.addClassLoader(AccessController.doPrivileged(J2DoPrivHelper
+            .getClassLoaderAction(MetaDataRepository.class)));
+
+        Set<String> classes = getPersistentTypeNames(false, multi);
+        if (classes == null || classes.size() == 0) {
+            throw new MetaDataException(_loc.get("repos-initializeEager-none"));
+        }
+        if (_log.isTraceEnabled() == true) {
+            _log.trace(_loc.get("repos-initializeEager-found", classes));
+        }
+
+        List<Class> loaded = new ArrayList<Class>();
+        for (String c : classes) {
+            try {
+                Class<?> cls = AccessController.doPrivileged((J2DoPrivHelper.getForNameAction(c, true, multi)));
+                loaded.add(cls);
+                // This call may be unnecessary?
+                _factory.load(cls, MODE_ALL, multi);
+            } catch (PrivilegedActionException pae) {
+                throw new MetaDataException(_loc.get("repos-initializeEager-error"), pae);
+            }
+        }
+        resolveAll(multi);
+        
+        // Hook in this class as a listener and process registered classes list to populate _aliases list.
+        PCRegistry.addRegisterClassListener(this);
+        processRegisteredClasses(multi);
+        _locking = false;
+        _preloadComplete = true;
+    }
+    
+    /**
      * Return the metadata for the given class.
      *
      * @param cls the class to retrieve metadata for
@@ -282,7 +355,17 @@
      * @param mustExist if true, throws a {@link MetaDataException}
      * if no metadata is found
      */
-    public synchronized ClassMetaData getMetaData(Class cls,
+    public ClassMetaData getMetaData(Class cls, ClassLoader envLoader, boolean mustExist) {
+        if (_locking) {
+            return getMetaDataLocking(cls, envLoader, mustExist);
+        } else {
+            return getMetaDataInternal(cls, envLoader, mustExist);
+        }
+    }
+    private synchronized ClassMetaData getMetaDataLocking(Class cls, ClassLoader envLoader, boolean mustExist) {
+        return getMetaDataInternal(cls, envLoader, mustExist);
+    }
+    private ClassMetaData getMetaDataInternal(Class cls,
         ClassLoader envLoader, boolean mustExist) {
         if (cls != null &&
             DynamicPersistenceCapable.class.isAssignableFrom(cls))
@@ -403,14 +486,24 @@
      * @since 1.1.0
      */
     public Collection getAliasNames() {
-        Collection aliases = new HashSet();
+        if (_locking) {
+            return getAliasNamesLocking();
+        } else {
+            return getAliasNamesInternal();
+        }
+    }
+
+    private Collection getAliasNamesLocking() {
         synchronized (_aliases) {
-            for (Iterator iter = _aliases.entrySet().iterator();
-                iter.hasNext(); ) {
-                Map.Entry e = (Map.Entry) iter.next();
-                if (e.getValue() != null)
-                    aliases.add(e.getKey());
-            }
+            return getAliasNamesInternal();
+        }
+    }
+    private final Collection getAliasNamesInternal() {
+        Collection aliases = new HashSet();
+        for (Iterator iter = _aliases.entrySet().iterator(); iter.hasNext();) {
+            Map.Entry e = (Map.Entry) iter.next();
+            if (e.getValue() != null)
+                aliases.add(e.getKey());
         }
         return aliases;
     }
@@ -749,7 +842,17 @@
     /**
      * Return all the metadata instances currently in the repository.
      */
-    public synchronized ClassMetaData[] getMetaDatas() {
+    public ClassMetaData[] getMetaDatas() {
+        if (_locking) {
+            return getMetaDatasLocking();
+        } else {
+            return getMetaDatasInternal();
+        }
+    }
+    private synchronized ClassMetaData[] getMetaDatasLocking() {
+        return getMetaDatasInternal();
+    }
+    private ClassMetaData[] getMetaDatasInternal() {
         // prevent concurrent mod errors when resolving one metadata
         // introduces others
         ClassMetaData[] metas = (ClassMetaData[]) _metas.values().
@@ -803,13 +906,22 @@
 
         // synchronize on this rather than the map, because all other methods
         // that access _metas are synchronized on this
-        synchronized (this) {
-            if (_pawares.containsKey(cls))
-                throw new MetaDataException(_loc.get("pc-and-aware", cls));
-            _metas.put(cls, meta);
+        if (_locking) {
+            metasPutLocking(cls, meta);
+        } else {
+            metasPutInternal(cls, meta);
         }
+            
         return meta;
     }
+    private synchronized void metasPutLocking(Class cls, ClassMetaData meta){
+        metasPutInternal(cls, meta);
+    }
+    private void metasPutInternal(Class cls, ClassMetaData meta){
+        if (_pawares.containsKey(cls))
+            throw new MetaDataException(_loc.get("pc-and-aware", cls));
+        _metas.put(cls, meta);
+    }
     
     /**
      * Create a new class metadata instance.
@@ -927,7 +1039,17 @@
      *
      * @return true if removed, false if not in this repository
      */
-    public synchronized boolean removeMetaData(Class cls) {
+    public boolean removeMetaData(Class cls) {
+        if(_locking){
+            return removeMetaDataLocking(cls);
+        }else{
+            return removeMetaDataInternal(cls);
+        }
+    }
+    private synchronized boolean removeMetaDataLocking(Class cls) {
+        return removeMetaDataInternal(cls);
+    }
+    private boolean removeMetaDataInternal(Class cls) {
         if (cls == null)
             return false;
         if (_metas.remove(cls) != null) {
@@ -943,24 +1065,42 @@
      * Add the given metadata as declared interface implementation.
      */
     void addDeclaredInterfaceImpl(ClassMetaData meta, Class iface) {
+        if (_locking) {
+            addDeclaredInterfaceImplLocking(meta, iface);
+        } else {
+            addDeclaredInterfaceImplInternal(meta, iface);
+        }
+    }
+    void addDeclaredInterfaceImplLocking(ClassMetaData meta, Class iface) {
         synchronized (_impls) {
-            Collection vals = (Collection) _impls.get(iface);
-            
-            // check to see if the superclass already declares to avoid dups
-            if (vals != null) {
-                ClassMetaData sup = meta.getPCSuperclassMetaData();
-                for (; sup != null; sup = sup.getPCSuperclassMetaData())
-                    if (vals.contains(sup.getDescribedType()))
-                        return;
-            }
-            addToCollection(_impls, iface, meta.getDescribedType(), false);
+            addDeclaredInterfaceImplInternal(meta, iface);
         }
     }
-
+    private void addDeclaredInterfaceImplInternal(ClassMetaData meta, Class iface) {
+        Collection vals = (Collection) _impls.get(iface);
+        // check to see if the superclass already declares to avoid dups
+        if (vals != null) {
+            ClassMetaData sup = meta.getPCSuperclassMetaData();
+            for (; sup != null; sup = sup.getPCSuperclassMetaData())
+                if (vals.contains(sup.getDescribedType()))
+                    return;
+        }
+        addToCollection(_impls, iface, meta.getDescribedType(), false);
+    }
     /**
      * Set the implementation for the given managed interface.
      */
-    synchronized void setInterfaceImpl(ClassMetaData meta, Class impl) {
+    void setInterfaceImpl(ClassMetaData meta, Class impl) {
+        if(_locking){
+            setInterfaceImplLocking(meta, impl);
+        }else{
+            setInterfaceImplInternal(meta, impl);
+        }
+    }
+    private synchronized void setInterfaceImplLocking(ClassMetaData meta, Class impl) {
+        setInterfaceImplInternal(meta, impl);
+    }
+    private void setInterfaceImplInternal(ClassMetaData meta, Class impl) {
         if (!meta.isManagedInterface())
             throw new MetaDataException(_loc.get("not-managed-interface", 
                 meta, impl));
@@ -1096,19 +1236,12 @@
         // get impls of given interface / abstract class
         loadRegisteredClassMetaData(envLoader);
         Collection vals = (Collection) _impls.get(cls);
-        ClassMetaData meta;
         Collection mapped = null;
         if (vals != null) {
-            synchronized (vals) {
-                for (Iterator itr = vals.iterator(); itr.hasNext();) {
-                    meta = getMetaData((Class) itr.next(), envLoader, true);
-                    if (meta.isMapped()
-                        || meta.getMappedPCSubclassMetaDatas().length > 0) {
-                        if (mapped == null)
-                            mapped = new ArrayList(vals.size());
-                        mapped.add(meta);
-                    }
-                }
+            if (_locking) {
+                mapped = getImplementorMetaDatasLocking(vals, envLoader, mustExist);
+            } else {
+                mapped = getImplementorMetaDatasInternal(vals, envLoader, mustExist);
             }
         }
 
@@ -1119,6 +1252,22 @@
         return (ClassMetaData[]) mapped.toArray(newClassMetaDataArray
             (mapped.size()));
     }
+    private Collection getImplementorMetaDatasLocking(Collection<Class> classes, ClassLoader envLoader, boolean mustExist) {
+        synchronized (classes) {
+            return getImplementorMetaDatasInternal(classes, envLoader, mustExist);
+        }
+    }
+    private Collection getImplementorMetaDatasInternal(Collection<Class> classes, ClassLoader envLoader, boolean mustExist) {
+        Collection mapped = new ArrayList(classes.size());
+        ClassMetaData meta = null;
+        for (Iterator itr = classes.iterator(); itr.hasNext();) {
+            meta = getMetaData((Class) itr.next(), envLoader, true);
+            if (meta.isMapped() || meta.getMappedPCSubclassMetaDatas().length > 0) {
+                mapped.add(meta);
+            }
+        }
+        return mapped;
+    }
      
     /**
      * Gets the metadata corresponding to the given persistence-aware class. 
@@ -1135,12 +1284,21 @@
      * @return empty array if no class has been registered as pers-aware
      */
     public NonPersistentMetaData[] getPersistenceAwares() {
+        if (_locking) {
+            return getPersistenceAwaresLocking();
+        } else {
+            return getPersistenceAwaresInternal();
+        }
+    }
+    private NonPersistentMetaData[] getPersistenceAwaresLocking() {
         synchronized (_pawares) {
+            return getPersistenceAwaresInternal();
+        }
+    }
+    private NonPersistentMetaData[] getPersistenceAwaresInternal() {
             if (_pawares.isEmpty())
                 return EMPTY_NON_PERSISTENT;
-            return (NonPersistentMetaData[])_pawares.values().toArray
-                (new NonPersistentMetaData[_pawares.size()]);
-        }
+        return (NonPersistentMetaData[]) _pawares.values().toArray(new NonPersistentMetaData[_pawares.size()]);
     }
 
     /**
@@ -1151,17 +1309,26 @@
     public NonPersistentMetaData addPersistenceAware(Class cls) {
     	if (cls == null)
     		return null;
-        synchronized(this) {
+        if (_locking) {
+            return addPersistenceAwareLocking(cls);
+        } else {
+            return addPersistenceAwareInternal(cls);
+        }
+    }
+
+    private synchronized NonPersistentMetaData addPersistenceAwareLocking(Class cls) {
+        return addPersistenceAwareInternal(cls);
+    }
+
+    private NonPersistentMetaData addPersistenceAwareInternal(Class cls) {
             if (_pawares.containsKey(cls))
                 return (NonPersistentMetaData)_pawares.get(cls);
             if (getCachedMetaData(cls) != null)
                 throw new MetaDataException(_loc.get("pc-and-aware", cls));
-            NonPersistentMetaData meta = new NonPersistentMetaData(cls, this,
-                NonPersistentMetaData.TYPE_PERSISTENCE_AWARE);
+        NonPersistentMetaData meta = new NonPersistentMetaData(cls, this, NonPersistentMetaData.TYPE_PERSISTENCE_AWARE);
             _pawares.put(cls, meta);
             return meta;
     	}
-    }
 
     /**
      * Remove a persitence-aware class from the repository
@@ -1188,12 +1355,21 @@
      * @return empty array if no non-mapped interface has been registered.
      */
     public NonPersistentMetaData[] getNonMappedInterfaces() {
+        if(_locking){
+            return getNonMappedInterfacesLocking();   
+        }else{
+            return getNonMappedInterfacesInternal();
+        }
+    }
+    private NonPersistentMetaData[] getNonMappedInterfacesLocking() {
         synchronized (_nonMapped) {
+            return getNonMappedInterfacesInternal();
+        }
+    }
+    private NonPersistentMetaData[] getNonMappedInterfacesInternal() {
             if (_nonMapped.isEmpty())
                 return EMPTY_NON_PERSISTENT;
-            return (NonPersistentMetaData[])_nonMapped.values().toArray
-                (new NonPersistentMetaData[_nonMapped.size()]);
-        }
+        return (NonPersistentMetaData[]) _nonMapped.values().toArray(new NonPersistentMetaData[_nonMapped.size()]);
     }
 
     /**
@@ -1206,7 +1382,17 @@
     		return null;
         if (!iface.isInterface())
             throw new MetaDataException(_loc.get("not-non-mapped", iface));
-        synchronized(this) {
+        if(_locking){
+            return addNonMappedInterfaceLocking(iface);
+        }else{
+            return addNonMappedInterfaceInternal(iface); 
+        }
+    }
+    private synchronized NonPersistentMetaData addNonMappedInterfaceLocking(Class iface) {
+        return addNonMappedInterfaceInternal(iface);
+    }
+    
+    private NonPersistentMetaData addNonMappedInterfaceInternal(Class iface) {
             if (_nonMapped.containsKey(iface))
                 return (NonPersistentMetaData)_nonMapped.get(iface);
             if (getCachedMetaData(iface) != null)
@@ -1216,7 +1402,6 @@
             _nonMapped.put(iface, meta);
             return meta;
     	}
-    }
 
     /**
      * Remove a non-mapped interface from the repository
@@ -1231,10 +1416,21 @@
      * Clear the cache of parsed metadata. This method also clears the
      * internal {@link MetaDataFactory MetaDataFactory}'s cache.
      */
-    public synchronized void clear() {
+    public void clear() {
         if (_log.isTraceEnabled())
             _log.trace(_loc.get("clear-repos", this));
-
+        
+        if (_locking) {
+            clearLocking();
+        } else {
+            clearInternal();
+        }
+    }
+    private synchronized void clearLocking(){
+        clearInternal();
+    }
+    private void clearInternal(){
+        // Recreating these datastructures is probably faster than calling clear. Future change?
         _metas.clear();
         _oids.clear();
         _subs.clear();
@@ -1247,7 +1443,6 @@
         _pawares.clear();
         _nonMapped.clear();
     }
-
     /**
      * Return the set of configured persistent classes, or null if the user
      * did not configure any.
@@ -1256,8 +1451,18 @@
      * in the classpath if no classes are configured explicitly
      * @param envLoader the class loader to use, or null for default
      */
-    public synchronized Set getPersistentTypeNames(boolean devpath,
+    public Set getPersistentTypeNames(boolean devpath,
         ClassLoader envLoader) {
+        if (_locking) {
+            return getPersistentTypeNamesLocking(devpath, envLoader);
+        } else {
+            return getPersistentTypeNamesInternal(devpath, envLoader);
+        }
+    }
+    private synchronized Set getPersistentTypeNamesLocking(boolean devpath, ClassLoader envLoader) {
+        return getPersistentTypeNamesInternal(devpath, envLoader);
+    }
+    private Set getPersistentTypeNamesInternal(boolean devpath, ClassLoader envLoader) {
         return _factory.getPersistentTypeNames(devpath, envLoader);
     }
 
@@ -1273,15 +1478,26 @@
      * @param envLoader the class loader to use, or null for default
      * @return the loaded classes, or empty collection if none
      */
-    public synchronized Collection loadPersistentTypes(boolean devpath,
+    public Collection loadPersistentTypes(boolean devpath,
         ClassLoader envLoader) {
+        if (_locking) {
+            return loadPersistentTypesLocking(devpath, envLoader);
+        } else {
+            return loadPersistentTypesInternal(devpath, envLoader);
+        }
+    }
+
+    private synchronized Collection loadPersistentTypesLocking(boolean devpath, ClassLoader envLoader) {
+        return loadPersistentTypesInternal(devpath, envLoader);
+    }
+
+    private Collection loadPersistentTypesInternal(boolean devpath, ClassLoader envLoader) {
         Set names = getPersistentTypeNames(devpath, envLoader);
         if (names == null || names.isEmpty())
             return Collections.EMPTY_LIST;
 
         // attempt to load classes so that they get processed
-        ClassLoader clsLoader = _conf.getClassResolverInstance().
-            getClassLoader(getClass(), envLoader);
+        ClassLoader clsLoader = _conf.getClassResolverInstance().getClassLoader(getClass(), envLoader);
         List classes = new ArrayList(names.size());
         Class cls;
         for (Iterator itr = names.iterator(); itr.hasNext();) {
@@ -1349,7 +1565,11 @@
     public void register(Class cls) {
         // buffer registered classes until an oid metadata request is made,
         // at which point we'll parse everything in the buffer
+        if (_locking) {
         synchronized (_registered) {
+                _registered.add(cls);
+            }
+        } else {
             _registered.add(cls);
         }
     }
@@ -1379,7 +1599,12 @@
         // copy into new collection to avoid concurrent mod errors on reentrant
         // registrations
         Class[] reg;
-        synchronized (_registered) {
+        if (_locking) {
+            synchronized (_registered) {
+                reg = (Class[]) _registered.toArray(new Class[_registered.size()]);
+                _registered.clear();
+            }
+        } else {
             reg = (Class[]) _registered.toArray(new Class[_registered.size()]);
             _registered.clear();
         }
@@ -1408,7 +1633,11 @@
             }
         }
         if (failed != null) {
-            synchronized (_registered) {
+            if(_locking){
+                synchronized (_registered) {
+                    _registered.addAll(failed);
+                }
+            }else{
                 _registered.addAll(failed);
             }
         }
@@ -1428,16 +1657,10 @@
         // update subclass lists; synchronize on this because accessing _metas
         // requires it
         Class leastDerived = cls;
-        synchronized (this) {
-            ClassMetaData meta;
-            for (Class anc = cls;
-                (anc = PCRegistry.getPersistentSuperclass(anc)) != null;) {
-                addToCollection(_subs, anc, cls, true);
-                meta = (ClassMetaData) _metas.get(anc);
-                if (meta != null)
-                    meta.clearSubclassCache();
-                leastDerived = anc;
-            }
+        if (_locking) {
+        	leastDerived = calcualteLeastDerivedLocking(cls);
+        } else {
+            leastDerived = calcualteLeastDerivedInternal(cls);
         }
 
         // update oid mappings if this is a base concrete class
@@ -1467,25 +1690,67 @@
 
         // update mappings from interfaces and non-pc superclasses to
         // pc implementing types
-        synchronized (_impls) {
+        if (_locking) {
+            synchronized (_impls) {
+                updateImpls(cls, leastDerived, cls);
+            }
+        } else {
             updateImpls(cls, leastDerived, cls);
         }
 
         // set alias for class
         String alias = PCRegistry.getTypeAlias(cls);
         if (alias != null) {
-            synchronized (_aliases) {
-                List classList = (List) _aliases.get(alias);
-                if (classList == null) {
-                    classList = new ArrayList(3);
-                    _aliases.put(alias, classList);
-                }
-                if (!classList.contains(cls))
-                    classList.add(cls);
+            if(_locking){
+                setAliasForClassLocking(alias, cls);
+            }else{
+                setAliasForClassInternal(alias, cls);
             }
         }
     }
-
+    /**
+     * Private worker method for use by processRegisterClasses.
+     */
+    private void setAliasForClassLocking(String alias, Class cls){
+        synchronized(_aliases){
+            setAliasForClassInternal(alias, cls);
+        }
+    }
+    /**
+     * Private worker method for use by processRegisterClasses.
+     */
+    private void setAliasForClassInternal(String alias, Class cls){
+        List classList = (List) _aliases.get(alias);
+        if (classList == null) {
+            classList = new ArrayList(3);
+            _aliases.put(alias, classList);
+        }
+        if (!classList.contains(cls))
+            classList.add(cls);
+    }
+    /**
+     * Private worker method for use by processRegisterClasses.
+     */
+    private synchronized Class calcualteLeastDerivedLocking(Class cls){
+        return calcualteLeastDerivedInternal(cls);
+    }
+    /**
+     * Private worker method for use by processRegisterClasses.
+     */
+    private Class calcualteLeastDerivedInternal(Class cls){
+        Class leastDerived = cls;
+        ClassMetaData meta;
+        for (Class anc = cls; (anc = PCRegistry.getPersistentSuperclass(anc)) != null;) {
+            addToCollection(_subs, anc, cls, true);
+            meta = (ClassMetaData) _metas.get(anc);
+            if (meta != null)
+                meta.clearSubclassCache();
+            leastDerived = anc;
+        }
+        
+        return leastDerived;
+    }
+    
     /**
      * Update the list of implementations of base classes and interfaces.
      */
@@ -1535,7 +1800,18 @@
      */
     private void addToCollection(Map map, Class key, Class value,
         boolean inheritance) {
+        if(_locking){
+            addToCollectionLocking(map, key, value, inheritance);
+        }else{
+            addToCollectionInternal(map, key, value, inheritance);
+        }
+    }
+    private void addToCollectionLocking(Map map, Class key, Class value, boolean inheritance) {
         synchronized (map) {
+            addToCollectionInternal(map, key, value, inheritance);
+        }
+    }
+    private void addToCollectionInternal(Map map, Class key, Class value, boolean inheritance) {
             Collection coll = (Collection) map.get(key);
             if (coll == null) {
                 if (inheritance) {
@@ -1548,7 +1824,6 @@
             }
             coll.add(value);
         }
-    }
 
     ///////////////////////////////
     // Configurable implementation
@@ -1567,6 +1842,16 @@
         initializeMetaDataFactory();
         if (_implGen == null)
             _implGen = new InterfaceImplGenerator(this);
+        if (_preload == true) {
+            _oids = new HashMap();
+            _impls = new HashMap();
+            _ifaces = new HashMap();
+            _aliases = new HashMap();
+            _pawares = new HashMap();
+            _nonMapped = new HashMap();
+            _subs = new HashMap();
+            // Wait till we're done loading MetaData to remove lock.
+        }            
     }
 
     private void initializeMetaDataFactory() {
@@ -1585,8 +1870,20 @@
     /**
      * Return query metadata for the given class, name, and classloader.
      */
-    public synchronized QueryMetaData getQueryMetaData(Class cls, String name,
+    public QueryMetaData getQueryMetaData(Class cls, String name,
         ClassLoader envLoader, boolean mustExist) {
+        if(_locking){
+            return getQueryMetaDataLocking(cls, name, envLoader, mustExist);
+        }else{
+            return getQueryMetaDataInternal(cls, name, envLoader, mustExist);
+        }
+    }
+    private synchronized QueryMetaData getQueryMetaDataLocking(Class cls, String name, ClassLoader envLoader,
+        boolean mustExist) {
+        return getQueryMetaDataInternal(cls, name, envLoader, mustExist);
+    }
+
+    private QueryMetaData getQueryMetaDataInternal(Class cls, String name, ClassLoader envLoader, boolean mustExist) {
         QueryMetaData meta = getQueryMetaDataInternal(cls, name, envLoader);
         if (meta == null) {
             // load all the metadatas for all the known classes so that
@@ -1597,12 +1894,10 @@
 
         if (meta == null && mustExist) {
             if (cls == null) {
-                throw new MetaDataException(_loc.get
-                    ("no-named-query-null-class", 
-                        getPersistentTypeNames(false, envLoader), name));
+                throw new MetaDataException(_loc.get("no-named-query-null-class", getPersistentTypeNames(false,
+                    envLoader), name));
             } else {
-                throw new MetaDataException(_loc.get("no-named-query",
-                    cls, name));
+                throw new MetaDataException(_loc.get("no-named-query", cls, name));
             }
         }
 
@@ -1655,26 +1950,45 @@
     /**
      * Return the cached query metadata.
      */
-    public synchronized QueryMetaData[] getQueryMetaDatas() {
-        return (QueryMetaData[]) _queries.values().toArray
-            (new QueryMetaData[_queries.size()]);
+    public QueryMetaData[] getQueryMetaDatas() {
+        if (_locking) {
+            synchronized (this) {
+                return (QueryMetaData[]) _queries.values().toArray(new QueryMetaData[_queries.size()]);
+            }
+        } else {
+            return (QueryMetaData[]) _queries.values().toArray(new QueryMetaData[_queries.size()]);
+        }
     }
 
     /**
      * Return the cached query metadata for the given name.
      */
-    public synchronized QueryMetaData getCachedQueryMetaData(Class cls,
+    public QueryMetaData getCachedQueryMetaData(Class cls,
         String name) {
-        return (QueryMetaData) _queries.get(getQueryKey(cls, name));
+        if (_locking) {
+            synchronized (this) {
+                return (QueryMetaData) _queries.get(getQueryKey(cls, name));
+            }
+        } else {
+            return (QueryMetaData) _queries.get(getQueryKey(cls, name));
+        }
     }
 
     /**
      * Add a new query metadata to the repository and return it.
      */
-    public synchronized QueryMetaData addQueryMetaData(Class cls, String name) {
-        QueryMetaData meta = newQueryMetaData(cls, name);
-        _queries.put(getQueryKey(meta), meta);
-        return meta;
+    public QueryMetaData addQueryMetaData(Class cls, String name) {
+        if (_locking) {
+            synchronized (this) {
+                QueryMetaData meta = newQueryMetaData(cls, name);
+                _queries.put(getQueryKey(meta), meta);
+                return meta;
+            }
+        }else{
+            QueryMetaData meta = newQueryMetaData(cls, name);
+            _queries.put(getQueryKey(meta), meta);
+            return meta;   
+        }
     }
 
     /**
@@ -1689,19 +2003,35 @@
     /**
      * Remove the given query metadata from the repository.
      */
-    public synchronized boolean removeQueryMetaData(QueryMetaData meta) {
-        if (meta == null)
-            return false;
-        return _queries.remove(getQueryKey(meta)) != null;
+    public  boolean removeQueryMetaData(QueryMetaData meta) {
+        if(_locking){
+            synchronized (this) {
+                if (meta == null)
+                    return false;
+                return _queries.remove(getQueryKey(meta)) != null;
+            }
+        }else{
+            if (meta == null)
+                return false;
+            return _queries.remove(getQueryKey(meta)) != null;
+        }
     }
 
     /**
      * Remove query metadata for the given class name if in the repository.
      */
-    public synchronized boolean removeQueryMetaData(Class cls, String name) {
-        if (name == null)
-            return false;
-        return _queries.remove(getQueryKey(cls, name)) != null;
+    public boolean removeQueryMetaData(Class cls, String name) {
+        if (_locking) {
+            synchronized (this) {
+                if (name == null)
+                    return false;
+                return _queries.remove(getQueryKey(cls, name)) != null;
+            }
+        } else {
+            if (name == null)
+                return false;
+            return _queries.remove(getQueryKey(cls, name)) != null;
+        }
     }
 
     /**
@@ -1733,7 +2063,19 @@
     /**
      * Return sequence metadata for the given name and classloader.
      */
-    public synchronized SequenceMetaData getSequenceMetaData(String name,
+    public SequenceMetaData getSequenceMetaData(String name,
+        ClassLoader envLoader, boolean mustExist) {
+        if(_locking){
+            return getSequenceMetaDataLocking(name, envLoader, mustExist);
+        }else{
+            return getSequenceMetaDataInternal(name, envLoader, mustExist);
+        }
+    }
+    private synchronized SequenceMetaData getSequenceMetaDataLocking(String name,
+        ClassLoader envLoader, boolean mustExist) {
+        return getSequenceMetaDataInternal(name, envLoader, mustExist);
+    }
+    private SequenceMetaData getSequenceMetaDataInternal(String name,
         ClassLoader envLoader, boolean mustExist) {
         SequenceMetaData meta = getSequenceMetaDataInternal(name, envLoader);
         if (meta == null && SequenceMetaData.NAME_SYSTEM.equals(name)) {
@@ -1806,26 +2148,44 @@
     /**
      * Return the cached sequence metadata.
      */
-    public synchronized SequenceMetaData[] getSequenceMetaDatas() {
-        return (SequenceMetaData[]) _seqs.values().toArray
-            (new SequenceMetaData[_seqs.size()]);
+    public SequenceMetaData[] getSequenceMetaDatas() {
+        if (_locking) {
+            synchronized (this) {
+                return (SequenceMetaData[]) _seqs.values().toArray(new SequenceMetaData[_seqs.size()]);
+            }
+        } else {
+            return (SequenceMetaData[]) _seqs.values().toArray(new SequenceMetaData[_seqs.size()]);
+        }
     }
 
     /**
      * Return the cached a sequence metadata for the given name.
      */
-    public synchronized SequenceMetaData getCachedSequenceMetaData(
-        String name) {
-        return (SequenceMetaData) _seqs.get(name);
+    public SequenceMetaData getCachedSequenceMetaData(String name) {
+        if (_locking) {
+            synchronized (this) {
+                return (SequenceMetaData) _seqs.get(name);
+            }
+        } else {
+            return (SequenceMetaData) _seqs.get(name);
+        }
     }
 
     /**
      * Add a new sequence metadata to the repository and return it.
      */
-    public synchronized SequenceMetaData addSequenceMetaData(String name) {
-        SequenceMetaData meta = newSequenceMetaData(name);
-        _seqs.put(name, meta);
-        return meta;
+    public SequenceMetaData addSequenceMetaData(String name) {
+        if (_locking) {
+            synchronized (this) {
+                SequenceMetaData meta = newSequenceMetaData(name);
+                _seqs.put(name, meta);
+                return meta;
+            }
+        } else {
+            SequenceMetaData meta = newSequenceMetaData(name);
+            _seqs.put(name, meta);
+            return meta;
+        }
     }
 
     /**
@@ -1838,44 +2198,76 @@
     /**
      * Remove the given sequence metadata from the repository.
      */
-    public synchronized boolean removeSequenceMetaData(SequenceMetaData meta) {
-        if (meta == null)
-            return false;
-        return _seqs.remove(meta.getName()) != null;
+    public boolean removeSequenceMetaData(SequenceMetaData meta) {
+        if (_locking) {
+            synchronized (this) {
+                if (meta == null)
+                    return false;
+                return _seqs.remove(meta.getName()) != null;
+            }
+        } else {
+            if (meta == null)
+                return false;
+            return _seqs.remove(meta.getName()) != null;
+        }
     }
 
     /**
      * Remove sequence metadata for the name if in the repository.
      */
-    public synchronized boolean removeSequenceMetaData(String name) {
-        if (name == null)
-            return false;
-        return _seqs.remove(name) != null;
+    public boolean removeSequenceMetaData(String name) {
+        if (_locking) {
+            synchronized (this) {
+                if (name == null)
+                    return false;
+                return _seqs.remove(name) != null;
+            }
+        }else{
+            if (name == null)
+                return false;
+            return _seqs.remove(name) != null;
+        }
     }
 
     /**
      * Add the given system lifecycle listener.
      */
-    public synchronized void addSystemListener(Object listener) {
-        // copy to avoid issues with ListenerList and avoid unncessary
-        // locking on the list during runtime
-        LifecycleEventManager.ListenerList listeners = new
-            LifecycleEventManager.ListenerList(_listeners);
-        listeners.add(listener);
-        _listeners = listeners;
+    public void addSystemListener(Object listener) {
+        if (_locking) {
+            synchronized (this) {
+                // copy to avoid issues with ListenerList and avoid unncessary
+                // locking on the list during runtime
+                LifecycleEventManager.ListenerList listeners = new LifecycleEventManager.ListenerList(_listeners);
+                listeners.add(listener);
+                _listeners = listeners;
+            }
+        } else {
+            LifecycleEventManager.ListenerList listeners = new LifecycleEventManager.ListenerList(_listeners);
+            listeners.add(listener);
+            _listeners = listeners;
+        }
     }
 
     /**
      * Remove the given system lifecycle listener.
      */
-    public synchronized boolean removeSystemListener(Object listener) {
+    public boolean removeSystemListener(Object listener) {
+        if (_locking) {
+            return removeSystemListenerLocking(listener);
+        } else {
+            return removeSystemListenerInternal(listener);
+        }
+    }
+    private synchronized boolean removeSystemListenerLocking(Object listener) {
+        return removeSystemListenerInternal(listener);
+    }
+    private boolean removeSystemListenerInternal(Object listener) {
         if (!_listeners.contains(listener))
             return false;
 
         // copy to avoid issues with ListenerList and avoid unncessary
         // locking on the list during runtime
-        LifecycleEventManager.ListenerList listeners = new
-            LifecycleEventManager.ListenerList(_listeners);
+        LifecycleEventManager.ListenerList listeners = new LifecycleEventManager.ListenerList(_listeners);
         listeners.remove(listener);
         _listeners = listeners;
         return true;
@@ -1891,7 +2283,17 @@
     /**
      * Free the resources used by this repository. Closes all user sequences.
      */
-    public synchronized void close() {
+    public void close() {
+        if(_locking){
+            closeLocking();
+        }else{
+            closeInternal();
+        }
+    }
+    private synchronized void closeLocking() {
+        closeInternal();
+    }
+    private void closeInternal() {
         SequenceMetaData[] smds = getSequenceMetaDatas();
         for (int i = 0; i < smds.length; i++)
             smds[i].close();
@@ -1931,7 +2333,17 @@
      * @param fmd
      * @return XML metadata
      */
-    public synchronized XMLMetaData getXMLMetaData(FieldMetaData fmd) {
+    public XMLMetaData getXMLMetaData(FieldMetaData fmd) {
+        if(_locking){
+            return getXMLMetaDataLocking(fmd);
+        }else{
+            return getXMLMetaDataInternal(fmd);
+        }
+    }
+    private synchronized XMLMetaData getXMLMetaDataLocking(FieldMetaData fmd) {
+        return getXMLMetaDataInternal(fmd);
+    }
+    private XMLMetaData getXMLMetaDataInternal(FieldMetaData fmd) {
         Class cls = fmd.getDeclaredType();
         // check if cached before
         XMLMetaData xmlmeta = (XMLClassMetaData) _xmlmetas.get(cls);
@@ -1957,7 +2369,11 @@
         
         // synchronize on this rather than the map, because all other methods
         // that access _xmlmetas are synchronized on this
+        if(_locking){
         synchronized (this) {
+                    _xmlmetas.put(type, meta);
+                }
+        }else{
             _xmlmetas.put(type, meta);
         }
         return meta;
@@ -1992,6 +2408,17 @@
     public XMLFieldMetaData newXMLFieldMetaData(Class type, String name) {
         return new XMLFieldMetaData(type, name);
     }
+    
+    /**
+     * This helper method returns true if Options paramater has the property Preload
+     * set to true.
+     */
+    public static boolean needsPreload(Options o) {
+        if (o.getBooleanProperty(PRELOAD_STR) == true) {
+            return true;
+        }
+        return false;
+    }
 
     /**
      * Analyzes the list of ClassMetaData in the supplied list for any which has foreign keys to other ClassMetaData 
@@ -2090,7 +2517,6 @@
         return returnList;
     }
 
-
     /**
      * Linked list node class for managing any foreign keys in the identity of a ClassMetaData instance.
      * 

Modified: openjpa/branches/1.2.x/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties (original)
+++ openjpa/branches/1.2.x/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties Tue Dec  8 21:51:26 2009
@@ -324,3 +324,8 @@
 cmd-discover-cycle: A cycle was detected while resolving the identity \
     references for type "{0}".  The original process buffer ordering \
     will be used.
+repos-initializeEager-none: No persistent metadata found for loading during initialization. \
+    The persistent classes must be listed in persistence unit configuration to be loaded during initialization.
+repos-initializeEager-found: The following classes are being preloaded "{0}".	   
+repos-initializeEager-error: Unexpected error during early loading of entity metadata during initialization. \
+    See nested stacktrace for details.	  

Modified: openjpa/branches/1.2.x/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java (original)
+++ openjpa/branches/1.2.x/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java Tue Dec  8 21:51:26 2009
@@ -905,9 +905,9 @@
      *   
      * @return MultiClassLoader
      */
-    public static final PrivilegedAction newMultiClassLoaderAction() {
+    public static final PrivilegedAction<MultiClassLoader> newMultiClassLoaderAction() {
         return new PrivilegedAction() {
-            public Object run() {
+            public MultiClassLoader run() {
                 return new MultiClassLoader();
             }
         };

Modified: openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java (original)
+++ openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java Tue Dec  8 21:51:26 2009
@@ -20,24 +20,30 @@
 
 import java.lang.instrument.ClassFileTransformer;
 import java.lang.instrument.IllegalClassFormatException;
+import java.security.AccessController;
 import java.security.ProtectionDomain;
 import java.util.Map;
+
 import javax.persistence.EntityManager;
 import javax.persistence.spi.ClassTransformer;
 import javax.persistence.spi.PersistenceProvider;
 import javax.persistence.spi.PersistenceUnitInfo;
 
 import org.apache.openjpa.conf.BrokerValue;
+import org.apache.openjpa.conf.MetaDataRepositoryValue;
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
 import org.apache.openjpa.enhance.PCClassFileTransformer;
+import org.apache.openjpa.kernel.AbstractBrokerFactory;
 import org.apache.openjpa.kernel.Bootstrap;
 import org.apache.openjpa.kernel.BrokerFactory;
 import org.apache.openjpa.lib.conf.Configuration;
 import org.apache.openjpa.lib.conf.ConfigurationProvider;
 import org.apache.openjpa.lib.conf.Configurations;
 import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
 import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Options;
 import org.apache.openjpa.meta.MetaDataModes;
 import org.apache.openjpa.meta.MetaDataRepository;
 import org.apache.openjpa.util.ClassResolver;
@@ -79,6 +85,8 @@
                 return null;
 
             BrokerFactory factory = getBrokerFactory(cp, poolValue, null);
+            preloadMetaDataRepository(factory);
+            
             return JPAFacadeHelper.toEntityManagerFactory(factory);
         } catch (Exception e) {
             throw PersistenceExceptions.toPersistenceException(e);
@@ -153,6 +161,7 @@
                         _loc.get("transformer-registration-error", pui));
                 }
             }
+            preloadMetaDataRepository(factory);           
             return JPAFacadeHelper.toEntityManagerFactory(factory);
         } catch (Exception e) {
             throw PersistenceExceptions.toPersistenceException(e);
@@ -177,6 +186,30 @@
     protected OpenJPAConfiguration newConfigurationImpl() {
         return new OpenJPAConfigurationImpl();
     }
+
+    /**
+     * Private worker method that will call to the MetaDataRepository to preload if the provided
+     * BrokerFactory is configured to do so.
+     */
+    private void preloadMetaDataRepository(BrokerFactory factory){
+        // We need to wait to preload until after we get back a fully configured/instantiated
+        // BrokerFactory. This is because it is possible that someone has extended OpenJPA
+        // functions and they need to be allowed time to configure themselves before we go off and
+        // start instanting configurable objects (ie:openjpa.MetaDataRepository). Don't catch
+        // any exceptions here because we want to fail-fast.
+        OpenJPAConfiguration conf = factory.getConfiguration();
+        Options o = Configurations.parseProperties(Configurations.getProperties(conf.getMetaDataRepository()));
+        if (MetaDataRepository.needsPreload(o) == true) {
+            MetaDataRepository mdr = conf.getMetaDataRepositoryInstance(); 
+            mdr.setValidate(MetaDataRepository.VALIDATE_RUNTIME, true);
+            mdr.setResolve(MetaDataRepository.MODE_MAPPING_INIT, true);
+            
+            // Load persistent classes and hook in subclasser
+            ((AbstractBrokerFactory) factory).loadPersistentTypes((ClassLoader) AccessController
+                .doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()));
+            mdr.preload();
+        }
+    }
     
     /**
      * Java EE 5 class transformer.