mkalen 2005/02/23 13:52:09
Modified: src/java/org/apache/ojb/broker/core/proxy Tag:
OJB_1_0_RELEASE CollectionProxyDefaultImpl.java
src/java/org/apache/ojb/broker/metadata Tag: OJB_1_0_RELEASE
MetadataManager.java
. Tag: OJB_1_0_RELEASE release-notes.txt
Log:
Fix bug when materialising dynamic proxy created with pre-thread metadata
changes activated. See thread at dev-list
http://mail-archives.apache.org/eyebrowse/[EMAIL PROTECTED]&msgNo=9143
Revision Changes Path
No revision
No revision
1.7.2.3 +59 -1
db-ojb/src/java/org/apache/ojb/broker/core/proxy/CollectionProxyDefaultImpl.java
Index: CollectionProxyDefaultImpl.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/proxy/CollectionProxyDefaultImpl.java,v
retrieving revision 1.7.2.2
retrieving revision 1.7.2.3
diff -u -r1.7.2.2 -r1.7.2.3
--- CollectionProxyDefaultImpl.java 16 Nov 2004 17:44:45 -0000 1.7.2.2
+++ CollectionProxyDefaultImpl.java 23 Feb 2005 21:52:08 -0000 1.7.2.3
@@ -26,6 +26,8 @@
import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.PersistenceBrokerException;
import org.apache.ojb.broker.PersistenceBrokerFactory;
+import org.apache.ojb.broker.metadata.MetadataManager;
+import org.apache.ojb.broker.metadata.MetadataException;
import org.apache.ojb.broker.core.PersistenceBrokerThreadMapping;
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.util.collections.IRemovalAwareCollection;
@@ -42,6 +44,10 @@
{
/** The key for acquiring the above broker */
private PBKey _brokerKey;
+ /** Flag set when per-thread metadata profiles are in use. */
+ private boolean _perThreadDescriptorsEnabled;
+ /** Profile key used when lazy-loading with per-thread metadata
profiles. */
+ private Object _profileKey;
/** The query that defines the values in the collection */
private Query _query;
/** The actual data (if already loaded) */
@@ -82,11 +88,31 @@
*/
public CollectionProxyDefaultImpl(PBKey brokerKey, Class collClass,
Query query)
{
+ MetadataManager mm = MetadataManager.getInstance();
+ _perThreadDescriptorsEnabled = mm.isEnablePerThreadChanges();
+ if (_perThreadDescriptorsEnabled) {
+ // mkalen: To minimize memory footprint we remember only the
OJB profile key
+ // (instead of all active class-mappings).
+ Object key = mm.getCurrentProfileKey();
+ if (key == null) {
+ // mkalen: Unsupported: using proxies with per-thread
metadata changes without profile keys.
+ throw new MetadataException("Trying to create a dynamic
proxy with per-thread metadata changes enabled, but no profile key.");
+ }
+ setProfileKey(key);
+ }
setBrokerKey(brokerKey);
setCollectionClass(collClass);
setQuery(query);
}
+ protected void loadProfile() {
+ Object key = getProfileKey();
+ if (key != null) {
+ MetadataManager mm = MetadataManager.getInstance();
+ mm.loadProfile(key);
+ }
+ }
+
/**
* Determines whether the collection data already has been loaded from
the database.
*
@@ -108,6 +134,9 @@
PersistenceBroker broker = getBroker();
try
{
+ if (_perThreadDescriptorsEnabled) {
+ loadProfile();
+ }
return broker.getCount(getQuery());
}
catch (Exception ex)
@@ -149,6 +178,9 @@
}
else if (_size != 0)
{
+ if (_perThreadDescriptorsEnabled) {
+ loadProfile();
+ }
// TODO: returned ManageableCollection should extend
Collection to avoid
// this cast
result = (Collection)
broker.getCollectionByQuery(getCollectionClass(), getQuery());
@@ -178,6 +210,9 @@
{
CollectionProxyListener listener;
+ if (_perThreadDescriptorsEnabled) {
+ loadProfile();
+ }
for (int idx = _listeners.size() - 1; idx >= 0; idx--)
{
listener = (CollectionProxyListener)_listeners.get(idx);
@@ -195,6 +230,9 @@
{
CollectionProxyListener listener;
+ if (_perThreadDescriptorsEnabled) {
+ loadProfile();
+ }
for (int idx = _listeners.size() - 1; idx >= 0; idx--)
{
listener = (CollectionProxyListener)_listeners.get(idx);
@@ -519,6 +557,26 @@
}
/**
+ * Returns the metadata profile key used when creating this proxy.
+ *
+ * @return brokerKey The key of the broker
+ */
+ protected Object getProfileKey()
+ {
+ return _profileKey;
+ }
+
+ /**
+ * Sets the metadata profile key used when creating this proxy.
+ *
+ * @param profileKey the metadata profile key
+ */
+ public void setProfileKey(Object profileKey)
+ {
+ _profileKey = profileKey;
+ }
+
+ /**
* Adds a listener to this collection.
*
* @param listener The listener to add
No revision
No revision
1.19.2.1 +21 -1
db-ojb/src/java/org/apache/ojb/broker/metadata/MetadataManager.java
Index: MetadataManager.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/MetadataManager.java,v
retrieving revision 1.19
retrieving revision 1.19.2.1
diff -u -r1.19 -r1.19.2.1
--- MetadataManager.java 12 Jun 2004 17:43:46 -0000 1.19
+++ MetadataManager.java 23 Feb 2005 21:52:09 -0000 1.19.2.1
@@ -131,6 +131,7 @@
private ConnectionRepository connectionRepository;
private boolean enablePerThreadChanges;
private PBKey defaultPBKey;
+ private Object currentProfileKey;
// singleton
private MetadataManager()
@@ -141,6 +142,7 @@
private void init()
{
metadataProfiles = new Hashtable();
+ currentProfileKey = null;
String repository = ((PersistenceBrokerConfiguration)
OjbConfigurator.getInstance()
.getConfigurationFor(null)).getRepositoryFilename();
try
@@ -489,10 +491,26 @@
{
throw new MetadataException("Can not find profile for key '" +
key + "'");
}
+ currentProfileKey = key;
setDescriptor(rep);
}
/**
+ * Returns the last activated profile key.
+ * @return the last activated profile key or null if no profile has been
loaded
+ * @throws MetadataException if per-thread changes has not been activated
+ * @see #loadProfile(Object)
+ */
+ public Object getCurrentProfileKey() throws MetadataException
+ {
+ if (!isEnablePerThreadChanges())
+ {
+ throw new MetadataException("Call to this method is undefined,
since per-thread mode is disabled.");
+ }
+ return currentProfileKey;
+ }
+
+ /**
* Remove the given metadata profile.
*/
public DescriptorRepository removeProfile(Object key)
@@ -506,6 +524,7 @@
public void clearProfiles()
{
metadataProfiles.clear();
+ currentProfileKey = null;
}
/**
@@ -517,6 +536,7 @@
public void removeAllProfiles()
{
metadataProfiles.clear();
+ currentProfileKey = null;
}
/**
No revision
No revision
1.54.2.26 +14 -1 db-ojb/release-notes.txt
Index: release-notes.txt
===================================================================
RCS file: /home/cvs/db-ojb/release-notes.txt,v
retrieving revision 1.54.2.25
retrieving revision 1.54.2.26
diff -u -r1.54.2.25 -r1.54.2.26
--- release-notes.txt 19 Feb 2005 23:46:17 -0000 1.54.2.25
+++ release-notes.txt 23 Feb 2005 21:52:09 -0000 1.54.2.26
@@ -386,6 +386,11 @@
are now deprecated but will NOT be removed in near future (so don't panic!).
CHANGES:
+- CollectionProxy classes will now throw an exception in constructor, if
trying
+to use dynamic proxies with MetadataManager in 'per thread changes' mode but
+without any metadata profile key loaded in the current thread. See note about
+fix in CollectionProxy under "BUG FIXES" below.
+
- fix bug in internal table OJB_HL_SEQ, column type of MAX_ID was INTEGER but
needs BIGINT to support Long on java side
@@ -417,6 +422,14 @@
under http://issues.apache.org/scarab/servlet/scarab/issues/id/OJBxxx
to see details for a bug with id OJBxxx.
+- fix bug in MetadataManager, when 'per thread changes' is enabled and
CollectionProxy
+proxies are used. Using proxies in this mode used to be undefined, since the
lazy
+loading might or might not succeed depending on in which thread the data was
loaded.
+OJB will now reload the metadata profile used when creating the proxy,
+before attempting to reference any persistence capable classes.
+(Fixes occasional ClassNotPersistenceCapable exceptions seen in multithreaded
+applications when using 'per thread changes'.)
+
- fix bug in MetadataManager, when 'per thread changes' is enabled and many
different
DescriptorRepository instances were used, gc can't collect unused instances
because
StatementManager doesn't release references to used DescriptorRepository
instances.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]