arminw 2005/09/06 15:16:11
Modified: src/java/org/apache/ojb/odmg 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
1.39 +25 -21 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.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- ObjectEnvelope.java 27 Aug 2005 12:29:02 -0000 1.38
+++ ObjectEnvelope.java 6 Sep 2005 22:16:11 -0000 1.39
@@ -131,7 +131,6 @@
if(beforeImage == null)
{
beforeImage = buildObjectImage(getBroker());
- //prepareToCompare();
}
return beforeImage;
}
@@ -141,7 +140,6 @@
if(currentImage == null)
{
currentImage = buildObjectImage(getBroker());
- //prepareToCompare();
}
return currentImage;
}
@@ -151,7 +149,7 @@
* to allow cleanup of used resources, e.g. remove proxy listener objects
* to avoid invoke of registered objects after tx end.
*/
- public void cleanup()
+ public void cleanup(boolean reuse)
{
if(currentImage != null)
{
@@ -159,7 +157,7 @@
while(iterator.hasNext())
{
EqualsBase base = (EqualsBase) iterator.next();
- if(base != null) base.cleanup();
+ if(base != null) base.cleanup(reuse);
}
}
if(beforeImage != null)
@@ -168,9 +166,11 @@
while(iterator.hasNext())
{
EqualsBase base = (EqualsBase) iterator.next();
- if(base != null) base.cleanup();
+ // we always free resources of the old image
+ if(base != null) base.cleanup(false);
}
}
+ if(!reuse) myObj = null;
}
public void refreshObjectImage()
@@ -354,17 +354,18 @@
}
else
{
- 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))
+ if(referenceObject != null
+ &&
BrokerHelper.hasAnonymousKeyReference(rds.getClassDescriptor(), rds))
{
getBroker().serviceBrokerHelper().link(myObj, rds, false);
}
+ erh = new EqualsRefHelper(referenceObject);
+ }
/*
register the Identity for 1:1 relations only, if change we have
to update the main object
@@ -396,7 +397,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;
@@ -522,8 +522,12 @@
}
/**
- * checks whether object and internal clone differ and returns true if
so, returns false else.
- * @return boolean
+ * For internal use only! Only call immediately before commit to
guarantee
+ * that all changes can be detected (because this method cache the
detected "change state"
+ * thus on eager call changes could be ignored). Checks whether object
and internal clone
+ * differ and returns <em>true</em> if so, returns <em>false</em> else.
+ *
+ * @return boolean The result.
*/
public boolean hasChanged(PersistenceBroker broker)
{
@@ -535,8 +539,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();
}
@@ -827,7 +833,7 @@
* to allow cleanup of used resources, e.g. remove proxy listener
objects
* to avoid invoke of registered objects after tx end.
*/
- abstract void cleanup();
+ abstract void cleanup(boolean reuse);
}
//====================================================
@@ -847,7 +853,7 @@
this.value = value;
}
- void cleanup()
+ void cleanup(boolean reuse)
{
}
@@ -899,7 +905,7 @@
this.oid = oid;
}
- void cleanup()
+ void cleanup(boolean reuse)
{
}
@@ -954,7 +960,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
{
@@ -962,14 +968,12 @@
private CollectionProxy collectionHandler;
private int status;
private Map references;
- // private Collection proxyData;
public EqualsColHelper(CollectionDescriptor des, Object collOrArray)
{
this.des = des;
references = new HashMap();
assignReferenceObject(collOrArray);
- //System.out.println("** Create " + this);
}
public String toString()
@@ -993,9 +997,9 @@
return (obj instanceof EqualsColHelper);
}
- void cleanup()
+ void cleanup(boolean reuse)
{
- if(collectionHandler != null)
+ if(!reuse && collectionHandler != null)
{
collectionHandler.removeListener(this);
collectionHandler = null;
1.45 +45 -51
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.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- ObjectEnvelopeTable.java 27 Aug 2005 12:29:02 -0000 1.44
+++ ObjectEnvelopeTable.java 6 Sep 2005 22:16:11 -0000 1.45
@@ -127,10 +127,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();
@@ -170,7 +170,7 @@
// 3. upgrade implicit locks.
//upgradeImplicitLocksAndCheckIfCommitIsNeeded();
- upgradeLockIfNeededAndCleanupBeforeCommit();
+ upgradeLockIfNeeded();
// 4. Reorder objects
reorder();
@@ -182,13 +182,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
- if(needsReusePrepare) prepareForReuse();
+ prepareForReuse(reuse);
// 6. commit cleanup
afterWriteCleanup();
@@ -232,38 +232,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)
+ {
+ boolean insert = mod.needsInsert();
+ mod.getModificationState().commit(mod);
+ if(reuse && insert)
{
- ObjectEnvelope mod = (ObjectEnvelope)
mhtObjectEnvelopes.get(iter.next());
- boolean insert = mod.needsInsert();
- mod.getModificationState().commit(mod);
- if(needsReusePrepare && insert)
- {
- getTransaction().doSingleLock(mod.getClassDescriptor(),
mod.getObject(), mod.getIdentity(), Transaction.WRITE);
- }
+ 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();
}
/**
@@ -284,27 +281,30 @@
* This method have to be called to reuse all registered [EMAIL
PROTECTED] ObjectEnvelope}
* objects after transaction commit/flush/checkpoint call.
*/
- private void prepareForReuse()
+ private void prepareForReuse(boolean reuse)
{
- // 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, cleanup the [EMAIL PROTECTED]
ObjectEnvelope}
* objects.
*/
- private void upgradeLockIfNeededAndCleanupBeforeCommit()
+ private void upgradeLockIfNeeded()
{
// using clone to avoid ConcurentModificationException
Iterator iter = ((List) mvOrderOfIds.clone()).iterator();
@@ -332,12 +332,6 @@
{
needsCommit = true;
}
- /*
- 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();
}
}
@@ -354,7 +348,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());
@@ -374,7 +368,7 @@
*/
public void remove(Object pKey)
{
- Identity id = null;
+ Identity id;
if (pKey instanceof Identity)
{
id = (Identity) pKey;
@@ -798,7 +792,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]