arminw 2005/07/07 10:03:05
Modified: src/java/org/apache/ojb/broker/accesslayer Tag:
OJB_1_0_RELEASE RsIterator.java
src/java/org/apache/ojb/broker/cache Tag: OJB_1_0_RELEASE
MaterializationCache.java
src/java/org/apache/ojb/broker/core Tag: OJB_1_0_RELEASE
PersistenceBrokerImpl.java
src/test/org/apache/ojb/broker Tag: OJB_1_0_RELEASE
BidirectionalAssociationTest.java
Log:
fix OJB-29
Revision Changes Path
No revision
No revision
1.63.2.10 +2 -2
db-ojb/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java
Index: RsIterator.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java,v
retrieving revision 1.63.2.9
retrieving revision 1.63.2.10
diff -u -r1.63.2.9 -r1.63.2.10
--- RsIterator.java 4 Mar 2005 18:07:22 -0000 1.63.2.9
+++ RsIterator.java 7 Jul 2005 17:03:03 -0000 1.63.2.10
@@ -501,7 +501,7 @@
getQueryObject().getClassDescriptor().getRowReader().readObjectArrayFrom(getRsAndStmt().m_rs,
getRow());
getQueryObject().getClassDescriptor().getRowReader().refreshObject(result,
getRow());
}
- getBroker().refreshRelationships(result, cld);
+ getBroker().checkRefreshRelationships(result, oid, cld);
}
return result;
No revision
No revision
1.1.2.4 +9 -1
db-ojb/src/java/org/apache/ojb/broker/cache/Attic/MaterializationCache.java
Index: MaterializationCache.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/cache/Attic/MaterializationCache.java,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -u -r1.1.2.3 -r1.1.2.4
--- MaterializationCache.java 18 Mar 2005 20:32:04 -0000 1.1.2.3
+++ MaterializationCache.java 7 Jul 2005 17:03:03 -0000 1.1.2.4
@@ -49,6 +49,14 @@
}
/**
+ * Returns <em>true</em> if the materialisation cache is enabled,
otherwise <em>false</em>.
+ */
+ public boolean isEnabledMaterialisationCache()
+ {
+ return enabledReadCache;
+ }
+
+ /**
* For internal use only! Helper method to guarantee that only full
materialized objects
* will be pushed to the application cache regardless if an local PB
transaction
* is running or not. When a complex object is materialized there will be
No revision
No revision
1.83.2.24 +49 -26
db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java
Index: PersistenceBrokerImpl.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java,v
retrieving revision 1.83.2.23
retrieving revision 1.83.2.24
diff -u -r1.83.2.23 -r1.83.2.24
--- PersistenceBrokerImpl.java 15 Jun 2005 19:31:57 -0000
1.83.2.23
+++ PersistenceBrokerImpl.java 7 Jul 2005 17:03:04 -0000
1.83.2.24
@@ -1301,7 +1301,7 @@
}
/**
- * retrieve all References (also Collection-attributes) of a given
instance.
+ * Retrieve all References (also Collection-attributes) of a given
instance.
* Loading is forced, even if the collection- and reference-descriptors
differ.
* @param pInstance the persistent instance to work with
*/
@@ -1312,8 +1312,6 @@
logger.debug("Manually retrieving all references for object " +
serviceIdentity().buildIdentity(pInstance));
}
ClassDescriptor cld = getClassDescriptor(pInstance.getClass());
- // force loading of references
- final boolean forced = true;
getInternalCache().enableMaterializationCache();
// to avoid problems with circular references, locally cache the
current object instance
Identity oid = serviceIdentity().buildIdentity(pInstance);
@@ -1325,8 +1323,8 @@
}
try
{
- referencesBroker.retrieveReferences(pInstance, cld, forced);
- referencesBroker.retrieveCollections(pInstance, cld, forced);
+ referencesBroker.retrieveReferences(pInstance, cld, true);
+ referencesBroker.retrieveCollections(pInstance, cld, true);
// do locally remove the object to avoid problems with object
state detection (insert/update),
// because objects found in the cache detected as 'old' means
'update'
if(needLocalRemove) getInternalCache().doLocalRemove(oid);
@@ -1395,37 +1393,62 @@
}
/**
- * Refresh Relationships
+ * Check if the references of the specified object have enabled
+ * the <em>refresh</em> sttribute.
*
* @throws PersistenceBrokerException if there is a error refreshing
collections or references
- * @param obj
- * @param cld
+ * @param obj The object to check.
+ * @param oid The [EMAIL PROTECTED] Identity} of the object.
+ * @param cld The [EMAIL PROTECTED]
org.apache.ojb.broker.metadata.ClassDescriptor} of the object.
*/
- public void refreshRelationships(Object obj, ClassDescriptor cld)
+ public void checkRefreshRelationships(Object obj, Identity oid,
ClassDescriptor cld)
{
Iterator iter;
CollectionDescriptor cds;
ObjectReferenceDescriptor rds;
- iter = cld.getCollectionDescriptors().iterator();
- while (iter.hasNext())
+ // to avoid problems with circular references, locally cache the
current object instance
+ Object tmp = getInternalCache().doLocalLookup(oid);
+ if(tmp != null && getInternalCache().isEnabledMaterialisationCache())
{
- cds = (CollectionDescriptor) iter.next();
- if (cds.isRefresh())
- {
- referencesBroker.retrieveCollection(obj, cld, cds, false);
- }
+ /*
+ arminw: This should fix OJB-29, infinite loops on bidirectional
1:1 relations with
+ refresh attribute 'true' for both references. OJB now assume
that the object is already
+ refreshed when it's cached in the materialisation cache
+ */
+ return;
}
- //
- // Refresh References
- //
- iter = cld.getObjectReferenceDescriptors().iterator();
- while (iter.hasNext())
+ try
{
- rds = (ObjectReferenceDescriptor) iter.next();
- if (rds.isRefresh())
+ getInternalCache().enableMaterializationCache();
+ if(tmp == null)
{
- referencesBroker.retrieveReference(obj, cld, rds, false);
+ getInternalCache().doInternalCache(oid, obj,
MaterializationCache.TYPE_UNKNOWN);
}
+ if(logger.isDebugEnabled()) logger.debug("Refresh relationships
for " + oid);
+ iter = cld.getCollectionDescriptors().iterator();
+ while (iter.hasNext())
+ {
+ cds = (CollectionDescriptor) iter.next();
+ if (cds.isRefresh())
+ {
+ referencesBroker.retrieveCollection(obj, cld, cds,
false);
+ }
+ }
+ iter = cld.getObjectReferenceDescriptors().iterator();
+ while (iter.hasNext())
+ {
+ rds = (ObjectReferenceDescriptor) iter.next();
+ if (rds.isRefresh())
+ {
+ referencesBroker.retrieveReference(obj, cld, rds, false);
+ }
+ }
+ getInternalCache().disableMaterializationCache();
+ }
+ catch(RuntimeException e)
+ {
+ getInternalCache().doLocalClear();
+ throw e;
}
}
@@ -1643,7 +1666,7 @@
refreshInstance(obj, id, cld);
}
// now refresh all references
- refreshRelationships(obj, cld);
+ checkRefreshRelationships(obj, id, cld);
}
// Invoke events on PersistenceBrokerAware instances and listeners
No revision
No revision
1.5.2.1 +61 -26
db-ojb/src/test/org/apache/ojb/broker/BidirectionalAssociationTest.java
Index: BidirectionalAssociationTest.java
===================================================================
RCS file:
/home/cvs/db-ojb/src/test/org/apache/ojb/broker/BidirectionalAssociationTest.java,v
retrieving revision 1.5
retrieving revision 1.5.2.1
diff -u -r1.5 -r1.5.2.1
--- BidirectionalAssociationTest.java 22 Jun 2004 18:16:22 -0000 1.5
+++ BidirectionalAssociationTest.java 7 Jul 2005 17:03:04 -0000 1.5.2.1
@@ -1,14 +1,14 @@
-/**
- * Author: Matthew Baird
- * [EMAIL PROTECTED]
- */
package org.apache.ojb.broker;
-import junit.framework.TestCase;
-import org.apache.ojb.broker.query.*;
-import org.apache.ojb.junit.PBTestCase;
-
import java.util.Iterator;
+import java.util.Collection;
+
+import org.apache.ojb.broker.query.Criteria;
+import org.apache.ojb.broker.query.Query;
+import org.apache.ojb.broker.query.QueryFactory;
+import org.apache.ojb.broker.metadata.ClassDescriptor;
+import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
+import org.apache.ojb.junit.PBTestCase;
/**
* tests a bidirectional association A<-->B
@@ -30,32 +30,57 @@
public void setUp() throws Exception
{
super.setUp();
- testCreateWithUpdate();
}
public void tearDown() throws Exception
{
+ super.tearDown();
+ }
+
+ public void testAutoRefreshTrue()
+ {
+ String pkSuffix = "_" + System.currentTimeMillis();
+ ObjectReferenceDescriptor ord_A = null;
+ ObjectReferenceDescriptor ord_B = null;
+ ClassDescriptor cld_A =
broker.getClassDescriptor(BidirectionalAssociationObjectA.class);
+ ord_A = cld_A.getObjectReferenceDescriptorByName("relatedB");
+ ClassDescriptor cld_B =
broker.getClassDescriptor(BidirectionalAssociationObjectB.class);
+ ord_B = cld_B.getObjectReferenceDescriptorByName("relatedA");
+ boolean oldA = ord_A.isRefresh();
+ boolean oldB = ord_B.isRefresh();
try
{
- deleteAllA();
- deleteAllB();
+ ord_A.setRefresh(true);
+ ord_B.setRefresh(true);
+ createWithUpdate(pkSuffix);
+ Criteria crit = new Criteria();
+ crit.addLike("pk", "%" + pkSuffix);
+ Query query =
QueryFactory.newQuery(BidirectionalAssociationObjectB.class, crit);
+ Collection result = broker.getCollectionByQuery(query);
+ assertEquals(1, result.size());
}
finally
{
- super.tearDown();
+ if(ord_A != null) ord_A.setRefresh(oldA);
+ if(ord_B != null) ord_B.setRefresh(oldB);
}
+ }
+ public void testCreateDelete()
+ {
+ String pkSuffix = "_" + System.currentTimeMillis();
+ createWithUpdate(pkSuffix);
+ deleteAllA();
+ deleteAllB();
}
- public void testCreateWithUpdate()
+ private void createWithUpdate(String pkSuffix)
{
- if (broker.isInTransaction())
- broker.abortTransaction();
broker.beginTransaction();
BidirectionalAssociationObjectA a = new
BidirectionalAssociationObjectA();
- a.setPk("A" + System.currentTimeMillis());
+ a.setPk("A" + pkSuffix);
BidirectionalAssociationObjectB b = new
BidirectionalAssociationObjectB();
- b.setPk("B" + System.currentTimeMillis());
+ b.setPk("B" + pkSuffix);
broker.store(a);
broker.store(b);
/**
@@ -73,8 +98,9 @@
public void testGetA() throws Exception
{
- if (broker.isInTransaction())
- broker.abortTransaction();
+ String pkSuffix = "_" + System.currentTimeMillis();
+ createWithUpdate(pkSuffix);
+
Criteria crit = new Criteria();
Query q;
Iterator iter;
@@ -89,12 +115,16 @@
fail("relatedB not found");
}
}
+
+ deleteAllA();
+ deleteAllB();
}
public void testGetB() throws Exception
{
- if (broker.isInTransaction())
- broker.abortTransaction();
+ String pkSuffix = "_" + System.currentTimeMillis();
+ createWithUpdate(pkSuffix);
+
Criteria crit = new Criteria();
Query q;
Iterator iter;
@@ -109,22 +139,29 @@
fail("relatedA not found");
}
}
+
+ deleteAllA();
+ deleteAllB();
}
public void testDeleteA()
{
+ String pkSuffix = "_" + System.currentTimeMillis();
+ createWithUpdate(pkSuffix);
deleteAllA();
+ deleteAllB();
}
public void testDeleteB()
{
+ String pkSuffix = "_" + System.currentTimeMillis();
+ createWithUpdate(pkSuffix);
deleteAllB();
+ deleteAllA();
}
private void deleteAllA()
{
- if (broker.isInTransaction())
- broker.abortTransaction();
Criteria crit = new Criteria();
Query q;
Iterator iter;
@@ -146,10 +183,8 @@
broker.commitTransaction();
}
- private void deleteAllB()
+ private void deleteAllB()
{
- if (broker.isInTransaction())
- broker.abortTransaction();
Criteria crit = new Criteria();
Query q;
Iterator iter;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]