OPENJPA-250: Correct MetaDataRepository plug-in configuration.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@820804 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Pinaki Poddar 2009-10-01 21:30:39 +00:00
parent fa02d2a5fa
commit 1ff5810e9e
8 changed files with 74 additions and 56 deletions

View File

@ -35,9 +35,7 @@ public class MetaDataRepositoryValue
extends PluginValue {
private static final String KEY = "MetaDataRepository";
private static final String PRELOAD_STR = "Preload=true";
private static final String NOLOCK_STR = "NoLock=true";
public MetaDataRepositoryValue() {
super(KEY, false);
String[] aliases = new String[] {
@ -49,25 +47,6 @@ public class MetaDataRepositoryValue
setString(aliases[0]);
}
public boolean getPreload() {
String p = getProperties();
if (p != null && p.indexOf(PRELOAD_STR) >= 0) {
return true;
} else if (getNoLock() == true) {
// No locking implies that we need to also preload.
// Return true regardless of the value of the
// preload flag.
return true;
}
return false;
}
public boolean getNoLock(){
String p = getProperties();
if (p != null && p.indexOf(NOLOCK_STR) >= 0) {
return true;
}
return false;
}
public Object instantiate(Class type, Configuration c, boolean fatal) {
MetaDataRepository repos = null;
OpenJPAConfiguration conf = (OpenJPAConfiguration) c;

View File

@ -333,7 +333,7 @@ public class OpenJPAConfigurationImpl
mapping = addString("Mapping");
metaFactoryPlugin = addPlugin("MetaDataFactory", false);
metaRepositoryPlugin = (MetaDataRepositoryValue)addValue(new MetaDataRepositoryValue());
metaRepositoryPlugin = addValue(new MetaDataRepositoryValue());
connectionFactory = addObject("ConnectionFactory");
connectionFactory.setInstantiatingGetter("getConnectionFactory");

View File

@ -60,6 +60,7 @@ import org.apache.openjpa.meta.MetaDataModes;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.util.GeneralException;
import org.apache.openjpa.util.InvalidStateException;
import org.apache.openjpa.util.MetaDataException;
import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.UserException;
import org.apache.openjpa.writebehind.WriteBehindCache;
@ -163,21 +164,24 @@ public abstract class AbstractBrokerFactory
_conf.getConnectionRetainModeConstant(), false).close();
}
// This logic needs to happen here for a reason! The preloading of the MDR
// can not happen during the configuration of the MDR because when running
// in a container environment we need to be able to get an uninitialized
// MDR to pass to the PCClassFileTransformer. If we preload before registering
// This eager metadata loading is invoked at construction.
// It can not happen during the MetaDataRepository configuration because
// within a container environment an uninitialized repository must be passed
// to the PCClassFileTransformer. If we attempt to load before registering
// the class transformer, we miss the class being defined by the JVM and in turn
// we fail to enhance our entities.
OpenJPAConfigurationImpl impl = (OpenJPAConfigurationImpl) config;
MetaDataRepositoryValue m = impl.metaRepositoryPlugin;
if (m.getPreload() == true) {
// Obtain a reference to the MetaDataRepository and trigger the preload
try {
MetaDataRepository mdr = config.getMetaDataRepositoryInstance();
mdr.preload();
} catch (MetaDataException e) {
// recognize metadata related error if using early initialization
throw e;
} catch (Throwable t) {
// swallow other errors because merely trying to obtain a repository
// may trigger a database connection
_conf.getConfigurationLog().error(_loc.get("factory-init-error",t));
}
initWriteBehindCallback();
initWriteBehindCallback();
}
/**

View File

@ -274,32 +274,58 @@ public class MetaDataRepository implements PCRegistry.RegisterClassListener, Con
_sourceMode &= ~mode;
}
/**
* Sets whether this repository will load all known persistent classes at initialization.
* Defaults to false.
*/
public boolean getPreload() {
return _preload;
}
/**
* Sets whether this repository will load all known persistent classes at initialization.
* Defaults to false.
*/
public void setPreload(boolean l) {
_preload = l;
}
/**
* Sets whether this repository will use unguarded access. Unguarded access
* can be safe if all metadata has been loaded at initialization.
*/
public void setNoLock(boolean l) {
_noLock = l;
}
/**
* Affirms whether this repository will use unguarded access. Unguarded access
* can be safe if all metadata has been loaded at initialization.
*/
public boolean getNoLock() {
return _noLock;
}
/**
* Loads all the known persistent classes if {@linkplain #setPreload(boolean) early loading}
* initialization has been set. The configuration must enlist all classes.
*
* <br>
* If {@linkplain #setNoLock(boolean) no lock} has been set then uses unguarded access to
* all internal data container structures.
* If the openjpa.MetaDataRepository plugin value preload=false is set, this method will noop.
* If preload=true this method gets the list of persistent classes and calls to the
* MetaDataFactory to load ALL metadata.
* <p>
*
* If noLock=true, calling this method will also remove ALL locking from this class.
* <p>
*
* NOTE : This method is not thread safe and should ONLY be called by the AbstractBrokerFactory
* constructor.
*
* @see #getPersistentTypeNames(boolean, ClassLoader)
*/
public void preload() {
if (_preload == false) {
if (!_preload) {
return;
}
if (_log.isTraceEnabled()) {
_log.trace("MetaDataRepository preload=" + _preload + ",noLock=" + _noLock);
if (_log.isInfoEnabled()) {
_log.info(_loc.get(_noLock ? "repos-preload" : "repos-preload-nolock"));
}
// Remove locking and use unsynchronized maps.
@ -319,15 +345,14 @@ public class MetaDataRepository implements PCRegistry.RegisterClassListener, Con
MultiClassLoader multi = AccessController.doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction());
multi.addClassLoader(AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()));
multi.addClassLoader(AccessController.doPrivileged(J2DoPrivHelper
.getClassLoaderAction(MetaDataRepository.class)));
.getClassLoaderAction(MetaDataRepository.class)));
Set<String> classes = getPersistentTypeNames(false, multi);
if (classes == null || classes.size() == 0) {
throw new RuntimeException("No persistent classes listed when trying to preload the MetaDataRepository");
throw new MetaDataException(_loc.get("repos-preload-none"));
}
if (_log.isTraceEnabled() == true) {
_log.trace(MetaDataRepository.class.getName()
+ " preloading the following classes : " + classes.toString());
if (_log.isTraceEnabled()) {
_log.trace(_loc.get("repos-preloading", this.getClass().getName(), classes.toString()));
}
for (String c : classes) {
@ -335,12 +360,9 @@ public class MetaDataRepository implements PCRegistry.RegisterClassListener, Con
Class<?> cls = AccessController.doPrivileged((J2DoPrivHelper.getForNameAction(c, true, multi)));
_factory.load(cls, MODE_ALL, multi);
} catch (PrivilegedActionException pae) {
// Unexpected!
if (_log.isTraceEnabled() == true) {
_log.trace(MetaDataRepository.class.getName() + " encountered an unexpected exception ", pae);
}
throw new MetaDataException(_loc.get("repos-preload-error"), pae);
}
}// end for
}
}
protected void lock() {

View File

@ -187,6 +187,8 @@ dup-load: Cannot load object with id "{0}". Instance "{1}" with the same id \
bad-id-value: The given value "{0}" cannot be converted into an identity \
for "{2}". The value is the wrong type ({1}).
factory-init: Starting OpenJPA {0}
factory-init-error: Error during initialization of configured properties: "{0}"\
The initialization will continue.
factory-properties: Properties: {0}
inverse-consistency: An inverse inconsistency in the object model was \
detected while flushing the field "{0}" of the instance with id "{1}" \

View File

@ -336,5 +336,15 @@ unexpected_proxy_sm_attribute_type: Unexpected attribute type "{1}" for \
inherited class(es) are packaged in the same jar file.
meta-no-model: Meta class "{0}" for entity {1} can not be registered with \
following exception "{2}"
no-mapped-by-in-mapped-super: Persistent relationship {0} defined by a mapped superclass {1} must be \
unidirectional.
no-mapped-by-in-mapped-super: Persistent relationship {0} defined by a mapped \
superclass {1} must be unidirectional.
repos-preload: Metadata is loaded during initialization. The persistent classes \
must be enlisted in configuration to be loaded during initialization.
repos-preload-nolock: Metadata is loaded during initialization with unguarded access. \
The persistent classes must be enlisted in configuration to be loaded during \
initialization.
repos-preload-none: No persistent metadata found for loading during initialization. \
The persistent classes must be enlisted in configuration to be loaded during initialization.
repos-preloading: Following metadata are being loaded during initialization by "{0}": {1}.
repos-preload-error: Unexpected error during early loading during initialization. \
See nested stacktrace for details.

View File

@ -158,7 +158,8 @@ public interface Configuration
* Add the given value to the set of configuration properties. This
* method replaces any existing value under the same property.
*/
public Value addValue(Value val);
public <T extends Value> T addValue(T val);
//public Value addValue(Value val);
/**
* Remove the given value from the set of configuration properties.

View File

@ -994,7 +994,7 @@ public class ConfigurationImpl
return true;
}
public Value addValue(Value val) {
public <T extends Value> T addValue(T val) {
_vals.add(val);
val.addListener(this);
return val;