arminw 2005/09/06 04:16:25
Modified: src/java/org/apache/ojb/odmg Tag: OJB_1_0_RELEASE
ObjectEnvelope.java ObjectEnvelopeTable.java
Log:
fix bug, remove proxy listener objects added while tx at the end of tx to
avoid problems with objects materialize outside of a tx and to allow gc of
added listener after tx end.
Revision Changes Path
No revision
No revision
1.32.2.17 +37 -39 db-ojb/src/java/org/apache/ojb/odmg/ObjectEnvelope.java
Index: ObjectEnvelope.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/ObjectEnvelope.java,v
retrieving revision 1.32.2.16
retrieving revision 1.32.2.17
diff -u -r1.32.2.16 -r1.32.2.17
--- ObjectEnvelope.java 22 Aug 2005 15:30:59 -0000 1.32.2.16
+++ ObjectEnvelope.java 6 Sep 2005 11:16:24 -0000 1.32.2.17
@@ -133,7 +133,6 @@
if(beforeImage == null)
{
beforeImage = buildObjectImage(getBroker());
- //prepareToCompare();
}
return beforeImage;
}
@@ -143,12 +142,16 @@
if(currentImage == null)
{
currentImage = buildObjectImage(getBroker());
- //prepareToCompare();
}
return currentImage;
}
- public void close()
+ /**
+ * This method should be called before transaction ends
+ * to allow cleanup of used resources, e.g. remove proxy listener objects
+ * to avoid invoke of registered objects after tx end.
+ */
+ public void cleanup(boolean reuse)
{
if(currentImage != null)
{
@@ -156,7 +159,7 @@
while(iterator.hasNext())
{
EqualsBase base = (EqualsBase) iterator.next();
- if(base != null) base.close();
+ if(base != null) base.cleanup(reuse);
}
}
if(beforeImage != null)
@@ -165,10 +168,11 @@
while(iterator.hasNext())
{
EqualsBase base = (EqualsBase) iterator.next();
- if(base != null) base.close();
+ // we always free resources of the old image
+ if(base != null) base.cleanup(false);
}
}
- myObj = null;
+ if(!reuse) myObj = null;
}
public void refreshObjectImage()
@@ -214,7 +218,7 @@
}
/**
- * returns the managed object.
+ * Returns the managed materialized object.
*/
public Object getObject()
{
@@ -357,19 +361,19 @@
}
else
{
+ /*
+ arminw:
+ if object was serialized and anonymous FK are used in the
main object, the FK
+ values are null, we have to refresh (re-assign) this values
before building field images
+ */
+ if(referenceObject != null
+ &&
BrokerHelper.hasAnonymousKeyReference(rds.getClassDescriptor(), rds))
+ {
+ getBroker().serviceBrokerHelper().link(myObj, rds,
false);
+ }
erh = new EqualsRefHelper(referenceObject);
}
/*
- arminw:
- if object was serialized and anonymous FK are used in the main
object, the FK
- values are null, we have to refresh (re-assign) this values
before building field images
- */
- if(handler == null && referenceObject != null
- &&
BrokerHelper.hasAnonymousKeyReference(rds.getClassDescriptor(), rds))
- {
- getBroker().serviceBrokerHelper().link(myObj, rds, false);
- }
- /*
register the Identity for 1:1 relations only, if change we have
to update the main object
*/
@@ -400,7 +404,6 @@
/**
* MBAIRD
* 3. now let's register the collection descriptors
- * How do we handle proxied collections and collections of proxies
*/
Iterator collections = mif.getCollectionDescriptors(true).iterator();
CollectionDescriptor cds;
@@ -539,8 +542,10 @@
{
log.warn("Could not verify object changes, return hasChanged
'true'", e);
}
- hasChanged = (beforeImage != null &&
beforeImage.equals(currentImage) ? Boolean.FALSE : Boolean.TRUE);
-
+ if(hasChanged == null)
+ {
+ hasChanged = (beforeImage != null &&
beforeImage.equals(currentImage) ? Boolean.FALSE : Boolean.TRUE);
+ }
return hasChanged.booleanValue();
}
@@ -826,8 +831,12 @@
*/
abstract class EqualsBase
{
- abstract void close();
- abstract void prepareForCompare();
+ /**
+ * This method is called before committing the transaction
+ * to allow cleanup of used resources, e.g. remove proxy listener
objects
+ * to avoid invoke of registered objects after tx end.
+ */
+ abstract void cleanup(boolean reuse);
}
//====================================================
@@ -847,11 +856,7 @@
this.value = value;
}
- void close()
- {
- }
-
- void prepareForCompare()
+ void cleanup(boolean reuse)
{
}
@@ -903,11 +908,7 @@
this.oid = oid;
}
- void close()
- {
- }
-
- void prepareForCompare()
+ void cleanup(boolean reuse)
{
}
@@ -962,7 +963,7 @@
// inner class
//====================================================
/**
- * Help to compare 1:1 references of the main object.
+ * Help to compare 1:n / m:n references of the main object.
*/
class EqualsColHelper extends EqualsBase implements
CollectionProxyListener
{
@@ -1001,17 +1002,14 @@
return (obj instanceof EqualsColHelper);
}
- void prepareForCompare()
- {
- }
-
- void close()
+ void cleanup(boolean reuse)
{
- if(collectionHandler != null)
+ if(!reuse && collectionHandler != null)
{
collectionHandler.removeListener(this);
collectionHandler = null;
}
+ hasChanged = null;
}
void assignReferenceObject(Object collOrArray)
1.32.2.21 +43 -43
db-ojb/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java
Index: ObjectEnvelopeTable.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java,v
retrieving revision 1.32.2.20
retrieving revision 1.32.2.21
diff -u -r1.32.2.20 -r1.32.2.21
--- ObjectEnvelopeTable.java 4 Jun 2005 14:38:13 -0000 1.32.2.20
+++ ObjectEnvelopeTable.java 6 Sep 2005 11:16:25 -0000 1.32.2.21
@@ -128,10 +128,10 @@
/**
* Perform write to DB on all registered object wrapper ([EMAIL
PROTECTED] ObjectEnvelope})
*
- * @param needsReusePrepare When all registered objects be re-used after
writing to
+ * @param reuse When all registered objects be re-used after writing to
* DB set <em>true</em>, else set <em>false</em> to improve performance.
*/
- public void writeObjects(boolean needsReusePrepare) throws
TransactionAbortedException, LockNotGrantedException
+ public void writeObjects(boolean reuse) throws
TransactionAbortedException, LockNotGrantedException
{
PersistenceBroker broker = transaction.getBroker();
ConnectionManagerIF connMan = broker.serviceConnectionManager();
@@ -183,13 +183,13 @@
// System.out.println("## ordering end");
// 5. write objects.
- writeAllEnvelopes(needsReusePrepare);
+ writeAllEnvelopes(reuse);
// 6. execute batch
connMan.executeBatch();
// 7. Update all Envelopes to new CleanState
- cleanupEnvelopes(needsReusePrepare);
+ prepareForReuse(reuse);
// 6. commit cleanup
afterWriteCleanup();
@@ -233,38 +233,35 @@
/**
* commit all envelopes against the current broker
*/
- private void writeAllEnvelopes(boolean needsReusePrepare)
+ private void writeAllEnvelopes(boolean reuse)
{
- if (needsCommit)
- {
- // remove m:n indirection table entries first
- performM2NUnlinkEntries();
+ // perform remove of m:n indirection table entries first
+ performM2NUnlinkEntries();
- Iterator iter;
- // using clone to avoid ConcurentModificationException
- iter = ((List) mvOrderOfIds.clone()).iterator();
- while (iter.hasNext())
+ Iterator iter;
+ // using clone to avoid ConcurentModificationException
+ iter = ((List) mvOrderOfIds.clone()).iterator();
+ while (iter.hasNext())
+ {
+ ObjectEnvelope mod = (ObjectEnvelope)
mhtObjectEnvelopes.get(iter.next());
+ if(needsCommit)
{
- ObjectEnvelope mod = (ObjectEnvelope)
mhtObjectEnvelopes.get(iter.next());
boolean insert = mod.needsInsert();
mod.getModificationState().commit(mod);
- if(needsReusePrepare && insert)
+ if(reuse && insert)
{
getTransaction().doSingleLock(mod.getClassDescriptor(),
mod.getObject(), mod.getIdentity(), Transaction.WRITE);
}
}
-
- // add m:n indirection table entries
- performM2NLinkEntries();
- }
- // if no objects changed, perform only the m:n stuff
- else
- {
- // remove m:n indirection table entries first
- performM2NUnlinkEntries();
- // add m:n indirection table entries
- performM2NLinkEntries();
+ /*
+ arminw: important to call this cleanup method for each registered
+ ObjectEnvelope, because this method will e.g. remove proxy
listener
+ objects for registered objects.
+ */
+ mod.cleanup(reuse);
}
+ // add m:n indirection table entries
+ performM2NLinkEntries();
}
/**
@@ -282,29 +279,32 @@
}
/**
- *
+ * This method have to be called to reuse all registered [EMAIL
PROTECTED] ObjectEnvelope}
+ * objects after transaction commit/flush/checkpoint call.
*/
- private void cleanupEnvelopes(boolean needsReusePrepare)
+ private void prepareForReuse(boolean reuse)
{
- // if we don't re-use ObjectEnvelope entries, don't cleanup
- if(!needsReusePrepare) return;
-
- // using clone to avoid ConcurentModificationException
- Iterator iter = ((List) mvOrderOfIds.clone()).iterator();
- while (iter.hasNext())
+ if(reuse)
{
- ObjectEnvelope mod = (ObjectEnvelope)
mhtObjectEnvelopes.get(iter.next());
- mod.refreshObjectImage();
- if(needsCommit && (mod.getModificationState() !=
StateOldClean.getInstance() || mod.getModificationState() !=
StateTransient.getInstance()))
+ // using clone to avoid ConcurentModificationException
+ Iterator iter = ((List) mvOrderOfIds.clone()).iterator();
+ while (iter.hasNext())
{
-
mod.setModificationState(mod.getModificationState().markClean());
+ ObjectEnvelope mod = (ObjectEnvelope)
mhtObjectEnvelopes.get(iter.next());
+ mod.refreshObjectImage();
+ if(needsCommit && (mod.getModificationState() !=
StateOldClean.getInstance()
+ || mod.getModificationState() !=
StateTransient.getInstance()))
+ {
+
mod.setModificationState(mod.getModificationState().markClean());
+ }
}
}
- }
+ }
/**
* Checks the status of all modified objects and
- * upgrade the lock if needed
+ * upgrade the lock if needed, cleanup the [EMAIL PROTECTED]
ObjectEnvelope}
+ * objects.
*/
private void upgradeLockIfNeeded()
{
@@ -350,7 +350,7 @@
ObjectEnvelope mod = (ObjectEnvelope)
mhtObjectEnvelopes.get(iter.next());
if (log.isDebugEnabled())
log.debug("rollback: " + mod);
- // if the Object has been modified has been modified by
transaction, mark object as dirty
+ // if the Object has been modified by transaction, mark
object as dirty
if (mod.hasChanged(transaction.getBroker()))
{
mod.setModificationState(mod.getModificationState().markDirty());
@@ -370,7 +370,7 @@
*/
public void remove(Object pKey)
{
- Identity id = null;
+ Identity id;
if (pKey instanceof Identity)
{
id = (Identity) pKey;
@@ -798,7 +798,7 @@
void performM2NLinkEntries()
{
PersistenceBroker broker = getTransaction().getBroker();
- LinkEntry entry = null;
+ LinkEntry entry;
for(int i = 0; i < m2nLinkList.size(); i++)
{
entry = (LinkEntry) m2nLinkList.get(i);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]