Author: arminw
Date: Tue Oct 31 09:08:15 2006
New Revision: 469559
URL: http://svn.apache.org/viewvc?view=rev&rev=469559
Log:
odmg-api performance improvement
Modified:
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/DatabaseImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ImplementationExt.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ImplementationImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/NamedRootsMap.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/NarrowTransaction.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelope.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/RuntimeObject.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionExt.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionImpl.java
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/DatabaseImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/DatabaseImpl.java?view=diff&rev=469559&r1=469558&r2=469559
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/DatabaseImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/DatabaseImpl.java Tue Oct 31 09:08:15 2006
@@ -34,9 +34,6 @@
/**
* Implementation class of the {@link org.odmg.Database} interface.
*
- * @author <a href="mailto:[email protected]">Thomas Mahler<a>
- * @author <a href="mailto:[email protected]">Matthew Baird</a>
- * @author <a href="mailto:[email protected]">Armin Waibel</a>
* @version $Id$
*/
public class DatabaseImpl implements org.odmg.Database
@@ -291,9 +288,8 @@
{
throw new TransactionNotInProgressException("No transaction in progress, cannot persist");
}
- RuntimeObject rt = new RuntimeObject(object, getTransaction());
+ RuntimeObject rt = new RuntimeObject(object, getTransaction(), true);
tx.makePersistent(rt);
-// tx.moveToLastInOrderList(rt.getIdentity());
}
/**
@@ -320,6 +316,5 @@
}
RuntimeObject rt = new RuntimeObject(object, tx);
tx.deletePersistent(rt);
-// tx.moveToLastInOrderList(rt.getIdentity());
}
}
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ImplementationExt.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ImplementationExt.java?view=diff&rev=469559&r1=469558&r2=469559
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ImplementationExt.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ImplementationExt.java Tue Oct 31 09:08:15 2006
@@ -133,44 +133,38 @@
*/
public void setOrdering(boolean ordering);
-// /**
-// * Returns whether or not the persistent method calls determine
-// * the persistent object order on commit.
-// *
-// * @see #setNoteUserOrder(boolean)
-// */
-// public boolean isNoteUserOrder();
-//
-// /**
-// * If <em>true</em> the order of persisting method calls like
-// * <br/> - {@link org.odmg.Transaction#lock(Object, int)}).
-// * <br/> - {@link org.odmg.Database#deletePersistent(Object)}).
-// * <br/> - {@link org.odmg.Database#makePersistent(Object)})
-// * determine the order of objects before commit.
-// * <br/>
-// * If <em>false</em> the ordering was determined by OJB's internal
-// * method calls and user calls.
-// * <br/>
-// * However it's possible to set this value only for the current
-// * used {@link org.odmg.Transaction} using {@link TransactionExt#setNoteUserOrder(boolean)}
-// * <p/>
-// * <strong>NOTE:</strong> If OJB's ordering algorithm (see
-// * {@link #setOrdering(boolean)}) is enabled, the
-// * order of objects may change on commit.
-// *
-// * @param noteUserOrder If <em>true</em> the order of persisting
-// * method calls determine the order of objects.
-// */
-// public void setNoteUserOrder(boolean noteUserOrder);
+ /**
+ * If returns <em>true</em> transient objects will be detected in an
+ * optimized and performant way.
+ *
+ * @see #setOptimizedTransientObjectDetection(boolean)
+ * @return The mode setting.
+ */
+ public boolean isOptimizedTransientObjectDetection();
-
-// /**
-// * Get object by OJB's {@link org.apache.ojb.broker.Identity}.
-// *
-// * @param id The identity of the object to look for.
-// * @return The matching object or <em>null</em>.
-// */
-// public Object getObjectByIdentity(Identity id);
+ /**
+ * The detection of transient objects could be costly (e.g. if a select of ID in
+ * database is used to check if object already exists) we do: <br/>
+ * a. Check if the object {@link org.apache.ojb.broker.Identity} mark the
+ * specified object as transient. If this is <em>false</em> the object has populated
+ * primary key fields, if <em>true</em> at least one PK field is <em>null</em>
+ * and the object is transient.
+ * <br/>
+ * b. Then we check if the object was already registered in current transaction.
+ * if <em>true</em> we can ask for transient state.
+ * <br/>
+ * c. If the primary key fields are mapped as <em>autoIncrement</em> fields and
+ * <em>optimizedTransientObjectDetection</em> is enabled OJB assume that the object
+ * is persistent.
+ * If the PK fields are not autoIncrement fields or the optimized detection is
+ * disabled a database <em>exists object</em> query is performed to check if the
+ * object is persistent or transient.
+ * <br/>
+ *
+ * @param optimizedTransientObjectDetection If <em>true</em> enable the optimized transient
+ * object detection for the whole application.
+ */
+ public void setOptimizedTransientObjectDetection(boolean optimizedTransientObjectDetection);
// /**
// * If set <em>true</em> the odmg implementation do it's best to find out the user intension, if set
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ImplementationImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ImplementationImpl.java?view=diff&rev=469559&r1=469558&r2=469559
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ImplementationImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ImplementationImpl.java Tue Oct 31 09:08:15 2006
@@ -68,6 +68,7 @@
private boolean implicitLockingBackward;
private boolean ordering;
private boolean managed = false;
+ private boolean optimizedTransientObjectDetection;
/**
* private Constructor: use static factory method
@@ -89,6 +90,7 @@
implicitLocking = conf.getBoolean("ImplicitLocking", true);
ordering = conf.getBoolean("Ordering", true);
implicitLockingBackward = conf.getBoolean("ImplicitLockingBackward", false);
+ optimizedTransientObjectDetection = conf.getBoolean("OptimizedTransientObjectDetection", true);
if(log.isEnabledFor(Logger.INFO))
{
log.info("Settings: " + this.toString());
@@ -420,6 +422,16 @@
public void setOrdering(boolean ordering)
{
this.ordering = ordering;
+ }
+
+ public boolean isOptimizedTransientObjectDetection()
+ {
+ return optimizedTransientObjectDetection;
+ }
+
+ public void setOptimizedTransientObjectDetection(boolean optimizedTransientObjectDetection)
+ {
+ this.optimizedTransientObjectDetection = optimizedTransientObjectDetection;
}
/**
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/NamedRootsMap.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/NamedRootsMap.java?view=diff&rev=469559&r1=469558&r2=469559
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/NamedRootsMap.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/NamedRootsMap.java Tue Oct 31 09:08:15 2006
@@ -24,7 +24,7 @@
import org.apache.ojb.broker.Identity;
import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.PersistenceBrokerException;
-import org.apache.ojb.broker.core.proxy.ProxyHelper;
+import org.apache.ojb.broker.PersistenceBrokerInternal;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.util.ObjectModification;
import org.apache.ojb.broker.util.logging.Logger;
@@ -214,11 +214,11 @@
public void bind(Object object, String name) throws ObjectNameNotUniqueException
{
boolean useIdentity = true;
- PersistenceBroker broker = tx.getBroker();
+ PersistenceBrokerInternal broker = tx.getBrokerInternal();
ClassDescriptor cld = null;
try
{
- cld = broker.getClassDescriptor(ProxyHelper.getRealClass(object));
+ cld = broker.getClassDescriptor(broker.getProxyFactory().getRealClass(object));
}
catch(PersistenceBrokerException ignore)
{
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/NarrowTransaction.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/NarrowTransaction.java?view=diff&rev=469559&r1=469558&r2=469559
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/NarrowTransaction.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/NarrowTransaction.java Tue Oct 31 09:08:15 2006
@@ -185,6 +185,16 @@
tx.setOrdering(ordering);
}
+ public boolean isOptimizedTransientObjectDetection()
+ {
+ return tx.isOptimizedTransientObjectDetection();
+ }
+
+ public void setOptimizedTransientObjectDetection(boolean optimizedTransientObjectDetection)
+ {
+ tx.setOptimizedTransientObjectDetection(optimizedTransientObjectDetection);
+ }
+
// public boolean isNoteUserOrder()
// {
// return tx.isNoteUserOrder();
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelope.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelope.java?view=diff&rev=469559&r1=469558&r2=469559
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelope.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelope.java Tue Oct 31 09:08:15 2006
@@ -15,20 +15,19 @@
* limitations under the License.
*/
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.Map;
import java.util.List;
-import java.util.ArrayList;
+import java.util.Map;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.OJBRuntimeException;
import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.PersistenceBrokerException;
-import org.apache.ojb.broker.OJBRuntimeException;
import org.apache.ojb.broker.PersistenceBrokerInternal;
import org.apache.ojb.broker.core.proxy.IndirectionHandler;
-import org.apache.ojb.broker.core.proxy.ProxyHelper;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.CollectionDescriptor;
import org.apache.ojb.broker.metadata.FieldDescriptor;
@@ -37,18 +36,20 @@
import org.apache.ojb.broker.util.ObjectModification;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
+import org.apache.ojb.odmg.link.LinkEntry;
+import org.apache.ojb.odmg.link.LinkEntryOneToN;
+import org.apache.ojb.odmg.link.LinkEntryOneToOne;
import org.apache.ojb.odmg.states.ModificationState;
import org.apache.ojb.odmg.states.StateNewDirty;
import org.apache.ojb.odmg.states.StateOldClean;
import org.apache.ojb.odmg.states.StateOldDirty;
-import org.apache.ojb.odmg.link.LinkEntry;
-import org.apache.ojb.odmg.link.LinkEntryOneToOne;
-import org.apache.ojb.odmg.link.LinkEntryOneToN;
+import org.odmg.Transaction;
/**
* ObjectEnvelope is used during ODMG transactions as a wrapper for a
* persistent objects declaration
*
+ * @version $Id: $
*/
public class ObjectEnvelope implements ObjectModification, Image.ImageListener
{
@@ -65,16 +66,20 @@
*/
private ModificationState modificationState = null;
private Identity oid;
+ private ClassDescriptor cld;
+ private PersistenceBrokerInternal broker;
private Boolean hasChanged;
private boolean writeLocked;
private boolean markedForCascadingInsert;
private boolean markedForCascadingDelete;
-
/**
- * myObj holds the object we are wrapping.
+ * The object to wrap (this can be a proxy object)
*/
private Object myObj;
-
+ /**
+ * The real object instance
+ */
+ private Object realObject;
/**
* beforeImage holds a mapping between field
* names and values at the start of the transaction.
@@ -95,15 +100,35 @@
this.linkEntryList = new ArrayList();
this.buffer = buffer;
this.oid = oid;
+ PersistenceBrokerInternal pb = getBroker();
+ myObj = obj;
+ // TODO: do we really need to materialize??
+ realObject = pb.getProxyFactory().getRealObject(obj);
+ prepareInitialState(isNewObject);
+ beforeImage = buildObjectImage(isNewObject);
+ }
+
+ ObjectEnvelope(ObjectEnvelopeTable buffer, Identity oid, ClassDescriptor cld, Object obj, boolean isNewObject)
+ {
+ this.linkEntryList = new ArrayList();
+ this.buffer = buffer;
+ this.oid = oid;
+ this.cld = cld;
+ PersistenceBrokerInternal pb = getBroker();
+ myObj = obj;
// TODO: do we really need to materialize??
- myObj = ProxyHelper.getRealObject(obj);
+ realObject = pb.getProxyFactory().getRealObject(obj);
prepareInitialState(isNewObject);
- beforeImage = buildObjectImage(getBroker(), isNewObject);
+ beforeImage = buildObjectImage(isNewObject);
}
public PersistenceBrokerInternal getBroker()
{
- return buffer.getTransaction().getBrokerInternal();
+ if(broker == null)
+ {
+ broker = buffer.getTransaction().getBrokerInternal();
+ }
+ return broker;
}
TransactionImpl getTx()
@@ -120,7 +145,7 @@
{
if(beforeImage == null)
{
- beforeImage = buildObjectImage(getBroker());
+ beforeImage = buildObjectImage(false);
}
return beforeImage;
}
@@ -129,7 +154,7 @@
{
if(currentImage == null)
{
- currentImage = buildObjectImage(getBroker(), needsInsert());
+ currentImage = buildObjectImage(needsInsert());
}
return currentImage;
}
@@ -141,6 +166,7 @@
*/
public void cleanup(boolean reuse, boolean wasInsert)
{
+ broker = null;
if(currentImage != null)
{
performImageCleanup(currentImage, reuse);
@@ -152,6 +178,14 @@
}
if(reuse)
{
+ if(wasInsert)
+ {
+ // if we reuse instance, replace transient identity object with real one
+ Identity oldOid = refreshIdentity();
+ buffer.replaceRegisteredIdentity(getIdentity(), oldOid);
+ // lock the new inserted object
+ buffer.getTransaction().internalSingleLock(getClassDescriptor(), getIdentity(), Transaction.WRITE);
+ }
refreshObjectImage(wasInsert);
// on reuse of this object, we have to clear the link list
if(linkEntryList.size() > 0) linkEntryList.clear();
@@ -159,15 +193,17 @@
else
{
myObj = null;
+ realObject = null;
}
+ cld = null;
}
private void performImageCleanup(Map imageMap, boolean reuse)
{
- Iterator iterator = imageMap.values().iterator();
+ Iterator iterator = imageMap.entrySet().iterator();
while(iterator.hasNext())
{
- Image base = (Image) iterator.next();
+ Image base = (Image) ((Map.Entry) iterator.next()).getValue();
if(base != null) base.cleanup(reuse);
}
}
@@ -178,7 +214,7 @@
{
markedForCascadingInsert = false;
markedForCascadingDelete = false;
-
+
// if an image already exists we
// replace the Identity too, maybe a temporary
// used PK value was replaced by the real one,
@@ -195,7 +231,7 @@
{
if(beforeImage == null)
{
- beforeImage = buildObjectImage(getBroker(), wasNewObject);
+ beforeImage = buildObjectImage(wasNewObject);
}
}
currentImage = null;
@@ -268,16 +304,23 @@
}
/**
- * Returns the managed materialized object.
+ * Returns the object (can be a proxy).
*/
public Object getObject()
{
return myObj;
}
+ /**
+ * Returns the real object (no proxy obj).
+ */
public Object getRealObject()
{
- return ProxyHelper.getRealObject(getObject());
+ if(realObject == null)
+ {
+ realObject = getBroker().getProxyFactory().getRealObject(getObject());
+ }
+ return realObject;
}
public void refreshObjectIfNeeded(Object obj)
@@ -285,6 +328,7 @@
if(this.myObj != obj)
{
this.myObj = obj;
+ this.realObject = null;
}
}
@@ -351,18 +395,10 @@
}
}
- /**
- * buildObjectImage() will return the image of the Object.
- */
- private Map buildObjectImage(PersistenceBroker broker) throws PersistenceBrokerException
- {
- return buildObjectImage(broker, false);
- }
-
- private Map buildObjectImage(PersistenceBroker broker, boolean isNew) throws PersistenceBrokerException
+ private Map buildObjectImage(boolean isNew) throws PersistenceBrokerException
{
Map imageMap = new HashMap();
- ClassDescriptor cld = broker.getClassDescriptor(getObject().getClass());
+ ClassDescriptor cld = getClassDescriptor();
//System.out.println("++++ build image: " + getObject());
// register 1:1 references in image
buildImageForSingleReferences(imageMap, cld);
@@ -376,11 +412,11 @@
private void buildImageForSingleReferences(Map imageMap, ClassDescriptor cld)
{
// register all 1:1 references
- Iterator iter = cld.getObjectReferenceDescriptors(true).iterator();
+ List ords = cld.getObjectReferenceDescriptors(true);
ObjectReferenceDescriptor rds;
- while(iter.hasNext())
+ for (int i = 0; i < ords.size(); i++)
{
- rds = (ObjectReferenceDescriptor) iter.next();
+ rds = (ObjectReferenceDescriptor) ords.get(i);
/*
arminw:
if a "super-reference" is matched (a 1:1 reference used to represent a super class)
@@ -388,9 +424,9 @@
*/
if(!rds.isSuperReferenceDescriptor())
{
- Object referenceObject = rds.getPersistentField().get(myObj);
+ Object referenceObject = rds.getPersistentField().get(getRealObject());
- IndirectionHandler handler = ProxyHelper.getIndirectionHandler(referenceObject);
+ IndirectionHandler handler = getBroker().getProxyFactory().getIndirectionHandler(referenceObject);
/*
arminw:
if object was serialized and anonymous FK are used in the main object, the FK
@@ -400,7 +436,7 @@
if(handler == null && referenceObject != null
&& BrokerHelper.hasAnonymousKeyReference(rds.getClassDescriptor(), rds))
{
- getBroker().serviceBrokerHelper().link(myObj, rds, false);
+ getBroker().serviceBrokerHelper().link(getRealObject(), rds, false);
}
Image.SingleRef singleRef = new Image.SingleRef(this, rds, referenceObject);
imageMap.put(rds, singleRef);
@@ -421,25 +457,19 @@
private void addFieldImage(Map imageMap, FieldDescriptor fld)
{
// register copies of all field values
- Object value = fld.getPersistentField().get(myObj);
- // get the real sql type value
- value = fld.getFieldConversion().javaToSql(value);
- // make copy of the sql type value
- value = fld.getJdbcType().getFieldType().copy(value);
- // buffer in image the field name and the sql type value
- // wrapped by a helper class
+ Object value = fld.getCopyOfValue(getRealObject());
imageMap.put(fld.getPersistentField().getName(), new Image.Field(fld.getJdbcType().getFieldType(), value));
}
private void buildImageForCollectionReferences(Map imageMap, ClassDescriptor cld)
{
// register the 1:n and m:n references
- Iterator collections = cld.getCollectionDescriptors(true).iterator();
+ List cdss = cld.getCollectionDescriptors(true);
CollectionDescriptor cds;
- while(collections.hasNext())
+ for(int i=0; i<cdss.size(); i++)
{
- cds = (CollectionDescriptor) collections.next();
- Object collectionOrArray = cds.getPersistentField().get(myObj);
+ cds = (CollectionDescriptor) cdss.get(i);
+ Object collectionOrArray = cds.getPersistentField().get(getRealObject());
Image.MultipleRef colRef = new Image.MultipleRef(this, cds, collectionOrArray);
imageMap.put(cds, colRef);
}
@@ -519,7 +549,6 @@
public boolean isDeleted(Identity id)
{
ObjectEnvelope envelope = buffer.getByIdentity(id);
-
return (envelope != null && envelope.needsDelete());
}
@@ -615,19 +644,22 @@
// these cases will be handled by ObjectEnvelopeTable#cascadingDependents()
// if(getModificationState().needsInsert() || getModificationState().needsDelete()) return;
+ Map newImage = null;
Map oldImage = getBeforeImage();
- Map newImage = getCurrentImage();
-
- Iterator iter = newImage.entrySet().iterator();
+ Iterator iter = oldImage.entrySet().iterator();
while (iter.hasNext())
{
- Map.Entry entry = (Map.Entry) iter.next();
- Object key = entry.getKey();
+ Map.Entry oldEntry = (Map.Entry) iter.next();
+ Object key = oldEntry.getKey();
// we only interested in references
if(key instanceof ObjectReferenceDescriptor)
{
- Image oldRefImage = (Image) oldImage.get(key);
- Image newRefImage = (Image) entry.getValue();
+ if(newImage == null)
+ {
+ newImage = getCurrentImage();
+ }
+ Image oldRefImage = (Image) oldEntry.getValue();
+ Image newRefImage = (Image) newImage.get(key);
newRefImage.performReferenceDetection(oldRefImage);
}
}
@@ -637,22 +669,21 @@
{
if(log.isDebugEnabled()) log.debug("Start UPDATE action for " + getIdentity());
performLinkEntries();
- getBroker().store(getObject(), getIdentity(), getClassDescriptor(), false, true);
+ getBroker().store(getRealObject(), getIdentity(), getClassDescriptor(), false, true);
}
public void doInsert()
{
if(log.isDebugEnabled()) log.debug("Start INSERT action for " + getIdentity());
performLinkEntries();
- getBroker().store(getObject(), getIdentity(), getClassDescriptor(), true, true);
- Identity oldOid = refreshIdentity();
- buffer.replaceRegisteredIdentity(getIdentity(), oldOid);
+ getBroker().store(getRealObject(), getIdentity(), getClassDescriptor(), true, true);
}
public void doDelete()
{
if(log.isDebugEnabled()) log.debug("Start DELETE action for " + getIdentity());
- getBroker().delete(getObject(), true);
+ // use specified object/proxyObject, because delete can be done without materialization
+ getBroker().delete(getObject(), getIdentity(), getClassDescriptor(), true);
}
public void doEvictFromCache()
@@ -693,7 +724,12 @@
ClassDescriptor getClassDescriptor()
{
- return getBroker().getClassDescriptor(ProxyHelper.getRealClass(getObject()));
+ if(cld == null)
+ {
+ PersistenceBrokerInternal broker = getBroker();
+ cld = broker.getClassDescriptor(broker.getProxyFactory().getRealClass(getObject()));
+ }
+ return cld;
}
void addLinkOneToOne(ObjectReferenceDescriptor ord, boolean unlink)
@@ -730,7 +766,7 @@
ObjectEnvelope oe = buffer.getByIdentity(oid);
if(oe == null)
{
- RuntimeObject rt = new RuntimeObject(refObjOrProxy, getTx());
+ RuntimeObject rt = new RuntimeObject(refObjOrProxy, oid, getTx());
// we don't use cascade locking, because new reference object
// will be detected by ObjectEnvelopeTable#cascadeMarkedForInsert()
getTx().lockAndRegister(rt, TransactionExt.READ, false);
@@ -765,8 +801,7 @@
// if the object isn't registered already, it can be 'new' or already 'persistent'
if(mod == null)
{
- boolean isNew = getTx().isTransient(null, refObjOrProxy, oid);
- mod = buffer.get(oid, refObjOrProxy, isNew);
+ mod = buffer.get(new RuntimeObject(refObjOrProxy, oid, getTx()));
}
// if the object was deleted in an previous action, mark as new
// to avoid deletion, else mark object as dirty to assign the FK of
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java?view=diff&rev=469559&r1=469558&r2=469559
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java Tue Oct 31 09:08:15 2006
@@ -22,7 +22,7 @@
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.ojb.broker.Identity;
-import org.apache.ojb.broker.core.proxy.ProxyHelper;
+import org.apache.ojb.broker.core.proxy.ProxyFactory;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.CollectionDescriptor;
import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
@@ -70,7 +70,6 @@
* we are done.
* </ol>
*
- * @author Gerhard Grosse
* @version $Id$
* @since Nov 15, 2004
*/
@@ -256,16 +255,16 @@
private void addEdgesForVertex(Vertex vertex)
{
ClassDescriptor cld = vertex.getEnvelope().getClassDescriptor();
- Iterator rdsIter = cld.getObjectReferenceDescriptors(true).iterator();
- while (rdsIter.hasNext())
+ List rdss = cld.getObjectReferenceDescriptors(true);
+ for (int i = 0; i < rdss.size(); i++)
{
- ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) rdsIter.next();
+ ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) rdss.get(i);
addObjectReferenceEdges(vertex, rds);
}
- Iterator cdsIter = cld.getCollectionDescriptors(true).iterator();
- while (cdsIter.hasNext())
+ List cdss = cld.getCollectionDescriptors(true);
+ for (int i = 0; i < cdss.size(); i++)
{
- CollectionDescriptor cds = (CollectionDescriptor) cdsIter.next();
+ CollectionDescriptor cds = (CollectionDescriptor) cdss.get(i);
addCollectionEdges(vertex, cds);
}
}
@@ -319,7 +318,8 @@
ObjectEnvelope envelope = vertex.getEnvelope();
Object col = cds.getPersistentField().get(envelope.getRealObject());
Object[] refObjects;
- if (col == null || (ProxyHelper.isCollectionProxy(col) && !ProxyHelper.getCollectionProxy(col).isLoaded()))
+ ProxyFactory pf = envelope.getBroker().getProxyFactory();
+ if (col == null || (pf.isCollectionProxy(col) && !pf.getCollectionProxy(col).isLoaded()))
{
refObjects = EMPTY_OBJECT_ARRAY;
}
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java?view=diff&rev=469559&r1=469558&r2=469559
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java Tue Oct 31 09:08:15 2006
@@ -18,9 +18,11 @@
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
@@ -29,11 +31,11 @@
import org.apache.ojb.broker.OJBRuntimeException;
import org.apache.ojb.broker.OptimisticLockException;
import org.apache.ojb.broker.PersistenceBroker;
+import org.apache.ojb.broker.PersistenceBrokerInternal;
import org.apache.ojb.broker.accesslayer.ConnectionManagerIF;
import org.apache.ojb.broker.core.proxy.CollectionProxy;
import org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl;
import org.apache.ojb.broker.core.proxy.IndirectionHandler;
-import org.apache.ojb.broker.core.proxy.ProxyHelper;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.CollectionDescriptor;
import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
@@ -52,11 +54,7 @@
* Manages all ObjectEnvelopes included by a transaction.
* Performs commit, and rollack operations on all included Envelopes.
*
- * @author Thomas Mahler
- * @author <a href="mailto:[email protected]">Matthew Baird</a>
- *
- * MBAIRD: added explicit closing and de-referencing to prevent any
- * GC issues.
+ * @version $Id: $
*/
public class ObjectEnvelopeTable
{
@@ -69,7 +67,7 @@
* as "delete". E.g. if a collection reference C is moved from object A1 to A2,
* then A1 wants to "delete" C and A2 wants to mark the new C object as "new".
*/
- private final List newAssociatedIdentites = new ArrayList();
+ private final Set newAssociatedIdentites = new HashSet();
private final List m2nLinkList = new ArrayList();
private final List m2nUnlinkList = new ArrayList();
@@ -271,10 +269,6 @@
{
insert = mod.needsInsert();
mod.getModificationState().commit(mod);
- if(reuse && insert)
- {
- getTransaction().internalSingleLock(mod.getClassDescriptor(), mod.getIdentity(), Transaction.WRITE);
- }
}
/*
arminw: important to call this cleanup method for each registered
@@ -294,10 +288,10 @@
*/
private void checkAllEnvelopes(PersistenceBroker broker)
{
- Iterator iter = ((List) objectEnvelopesOrderList.clone()).iterator();
- while(iter.hasNext())
+ List list = ((List) objectEnvelopesOrderList.clone());
+ for(int i = 0; i < list.size(); i++)
{
- ObjectEnvelope mod = (ObjectEnvelope) iter.next();
+ ObjectEnvelope mod = (ObjectEnvelope) list.get(i);
// transient and NewDelete objects must NOT performed
ModificationState state = mod.getModificationState();
if(!state.isTransient() && !(state.isNew() && state.isDelete()))
@@ -315,12 +309,12 @@
private void upgradeLockIfNeeded()
{
// using clone to avoid ConcurentModificationException
- Iterator iter = ((List) objectEnvelopesOrderList.clone()).iterator();
+ List list = ((List) objectEnvelopesOrderList.clone());
TransactionImpl tx = getTransaction();
ObjectEnvelope mod;
- while(iter.hasNext())
+ for(int i = list.size() - 1; i > -1; i--)
{
- mod = (ObjectEnvelope) iter.next();
+ mod = (ObjectEnvelope) list.get(i);
// no need to lock new objects
if(mod.getModificationState().isNew())
{
@@ -415,23 +409,46 @@
return (ObjectEnvelope) objectEnvelopesMap.get(id);
}
- /** retrieve an objects ObjectModification state from the hashtable */
- public boolean contains(Identity oid)
+ public boolean isRegistered(Identity oid)
{
return objectEnvelopesMap.containsKey(oid);
}
+ public ObjectEnvelope register(Object object, boolean isNew)
+ {
+ PersistenceBrokerInternal pb = transaction.getBrokerInternal();
+ ClassDescriptor cld = pb.getClassDescriptor(pb.getProxyFactory().getRealClass(object));
+ Identity oid = pb.serviceIdentity().buildIdentity(cld, object);
+ return register(oid, cld, object, isNew);
+ }
+
+ public ObjectEnvelope register(Identity oid, Object object, boolean isNew)
+ {
+ PersistenceBrokerInternal pb = transaction.getBrokerInternal();
+ ClassDescriptor cld = pb.getClassDescriptor(pb.getProxyFactory().getRealClass(object));
+ return register(oid, cld, object, isNew);
+ }
+
+ public ObjectEnvelope register(Identity oid, ClassDescriptor cld, Object object, boolean isNew)
+ {
+ ObjectEnvelope oe = new ObjectEnvelope(this, oid, cld, object, isNew);
+ objectEnvelopesMap.put(oid, oe);
+ objectEnvelopesOrderList.add(oe);
+ return oe;
+ }
+
/**
* retrieve an objects ObjectEnvelope state from the hashtable.
* If no ObjectEnvelope is found, a new one is created and returned.
*
* @return the resulting ObjectEnvelope
*/
- public ObjectEnvelope get(Object pKey, boolean isNew)
+ public ObjectEnvelope get(Object object, boolean isNew)
+ //public ObjectEnvelope registerIfNeeded(Object object, boolean isNew)
{
- PersistenceBroker broker = transaction.getBroker();
- Identity oid = broker.serviceIdentity().buildIdentity(pKey);
- return get(oid, pKey, isNew);
+ Identity oid = transaction.getBrokerInternal().serviceIdentity().buildIdentity(object);
+ //return registerObjectIfNeeded(oid, object, isNew);
+ return get(oid, object, isNew);
}
/**
@@ -440,19 +457,35 @@
*
* @return the resulting ObjectEnvelope
*/
- public ObjectEnvelope get(Identity oid, Object pKey, boolean isNew)
+ public ObjectEnvelope get(Identity oid, Object object, boolean isNew)
+ //public ObjectEnvelope registerIfNeeded(Identity oid, Object object, boolean isNew)
{
- ObjectEnvelope result = getByIdentity(oid);
- if(result == null)
+ ObjectEnvelope oe = getByIdentity(oid);
+ if(oe == null)
{
- result = new ObjectEnvelope(this, oid, pKey, isNew);
- objectEnvelopesMap.put(oid, result);
- objectEnvelopesOrderList.add(result);
- if(log.isDebugEnabled()) log.debug("Register: " + result);
+ oe = register(oid, object, isNew);
}
- return result;
+ return oe;
}
+ public ObjectEnvelope get(RuntimeObject rtObject)
+ //public ObjectEnvelope registerIfNeeded(Object object, boolean isNew)
+ {
+ ObjectEnvelope oe = getByIdentity(rtObject.getIdentity());
+ if(oe == null)
+ {
+ oe = register(rtObject);
+ }
+ return oe;
+ }
+
+ public ObjectEnvelope register(RuntimeObject rtObject)
+ {
+ return register(rtObject.getIdentity(), rtObject.getCld(), rtObject.getObj(), rtObject.isNew());
+ }
+
+
+
/** Returns a String representation of this object */
public String toString()
{
@@ -549,28 +582,29 @@
if(mod.isMarkedForCascadingInsert()) return;
mod.markForCascadingInsert();
- ClassDescriptor cld = getTransaction().getBroker().getClassDescriptor(mod.getObject().getClass());
+ ClassDescriptor cld = mod.getClassDescriptor();
List refs = cld.getObjectReferenceDescriptors(true);
- cascadeInsertSingleReferences(mod, refs);
+ if(refs.size() > 0) cascadeInsertSingleReferences(mod, refs);
List colls = cld.getCollectionDescriptors(true);
- cascadeInsertCollectionReferences(mod, colls);
+ if(colls.size() > 0) cascadeInsertCollectionReferences(mod, colls);
}
private void cascadeInsertSingleReferences(ObjectEnvelope source, List descriptor)
{
+ PersistenceBrokerInternal pb = getTransaction().getBrokerInternal();
for(int i = 0; i < descriptor.size(); i++)
{
ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) descriptor.get(i);
- Object depObj = ord.getPersistentField().get(source.getObject());
+ Object depObj = ord.getPersistentField().get(source.getRealObject());
if(depObj != null)
{
// in any case we have to link the source object when the object needs insert
source.addLinkOneToOne(ord, false);
- IndirectionHandler handler = ProxyHelper.getIndirectionHandler(depObj);
+ IndirectionHandler handler = pb.getProxyFactory().getIndirectionHandler(depObj);
// if the object is not materialized, nothing has changed
if(handler == null || handler.alreadyMaterialized())
{
@@ -602,12 +636,12 @@
private void cascadeInsertCollectionReferences(ObjectEnvelope source, List descriptor)
{
- // PersistenceBroker pb = getTransaction().getBroker();
+ PersistenceBrokerInternal pb = getTransaction().getBrokerInternal();
for(int i = 0; i < descriptor.size(); i++)
{
CollectionDescriptor col = (CollectionDescriptor) descriptor.get(i);
- Object collOrArray = col.getPersistentField().get(source.getObject());
- CollectionProxy proxy = ProxyHelper.getCollectionProxy(collOrArray);
+ Object collOrArray = col.getPersistentField().get(source.getRealObject());
+ CollectionProxy proxy = pb.getProxyFactory().getCollectionProxy(collOrArray);
/*
on insert we perform only materialized collection objects. This should be
sufficient, because in method #cascadingDependents() we make sure that on
@@ -638,7 +672,7 @@
object when the main object needs insert, because we have to assign the FK values
to the main object
*/
- colObj = ProxyHelper.getRealObject(colObj);
+ colObj = pb.getProxyFactory().getRealObject(colObj);
ObjectEnvelope oe = getByIdentity(oid);
if(oe == null)
{
@@ -648,12 +682,12 @@
if(col.isMtoNRelation())
{
// the main objects needs insert, thus add new m:n link
- addM2NLinkEntry(col, source.getObject(), colObj);
+ addM2NLinkEntry(col, source.getRealObject(), colObj);
}
else
{
// we mark collection reference for linking
- oe.addLinkOneToN(col, source.getObject(), false);
+ oe.addLinkOneToN(col, source.getRealObject(), false);
/*
arminw: The referenced object could be already persisted, so we have
to dirty it to guarantee the setting of the FK (linking)
@@ -678,7 +712,7 @@
if(mod.isMarkedForCascadingDelete()) return;
mod.markForCascadingDelete();
- ClassDescriptor cld = getTransaction().getBroker().getClassDescriptor(mod.getObject().getClass());
+ ClassDescriptor cld = mod.getClassDescriptor();
List refs = cld.getObjectReferenceDescriptors(true);
cascadeDeleteSingleReferences(mod, refs);
@@ -694,7 +728,7 @@
ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) descriptor.get(i);
if(getTransaction().cascadeDeleteFor(ord))
{
- Object depObj = ord.getPersistentField().get(source.getObject());
+ Object depObj = ord.getPersistentField().get(source.getRealObject());
if(depObj != null)
{
Identity oid = getTransaction().getBroker().serviceIdentity().buildIdentity(depObj);
@@ -713,14 +747,14 @@
private void cascadeDeleteCollectionReferences(ObjectEnvelope source, List descriptor)
{
- PersistenceBroker pb = getTransaction().getBroker();
+ PersistenceBrokerInternal pb = getTransaction().getBrokerInternal();
for(int i = 0; i < descriptor.size(); i++)
{
CollectionDescriptor col = (CollectionDescriptor) descriptor.get(i);
boolean cascadeDelete = getTransaction().cascadeDeleteFor(col);
- Object collOrArray = col.getPersistentField().get(source.getObject());
+ Object collOrArray = col.getPersistentField().get(source.getRealObject());
// TODO: remove cast
- CollectionProxyDefaultImpl proxy = (CollectionProxyDefaultImpl) ProxyHelper.getCollectionProxy(collOrArray);
+ CollectionProxyDefaultImpl proxy = (CollectionProxyDefaultImpl) pb.getProxyFactory().getCollectionProxy(collOrArray);
// on delete we have to materialize dependent objects
if(proxy != null)
{
@@ -731,7 +765,7 @@
Iterator it = BrokerHelper.getCollectionIterator(collOrArray);
while(it.hasNext())
{
- Object colObj = ProxyHelper.getRealObject(it.next());
+ Object colObj = pb.getProxyFactory().getRealObject(it.next());
Identity oid = pb.serviceIdentity().buildIdentity(colObj);
ObjectEnvelope colMod = get(oid, colObj, false);
if(cascadeDelete)
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/RuntimeObject.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/RuntimeObject.java?view=diff&rev=469559&r1=469558&r2=469559
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/RuntimeObject.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/RuntimeObject.java Tue Oct 31 09:08:15 2006
@@ -15,17 +15,16 @@
* limitations under the License.
*/
+import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.PersistenceBrokerInternal;
import org.apache.ojb.broker.core.proxy.IndirectionHandler;
-import org.apache.ojb.broker.core.proxy.ProxyHelper;
import org.apache.ojb.broker.metadata.ClassDescriptor;
-import org.apache.commons.lang.builder.ToStringBuilder;
/**
* Helper object encapsulates common used object properties/states, help to reduce
* needless metadata calls.
*
- * @author <a href="mailto:[email protected]">Armin Waibel</a>
* @version $Id$
*/
public final class RuntimeObject
@@ -41,7 +40,16 @@
{
this.tx = tx;
this.obj = obj;
- initCld(tx);
+ init(tx);
+ doIsNewObjectCheck(tx);
+ }
+
+ public RuntimeObject(final Object obj, final Identity oid, final TransactionImpl tx)
+ {
+ this.tx = tx;
+ this.obj = obj;
+ this.identity = oid;
+ init(tx);
doIsNewObjectCheck(tx);
}
@@ -50,7 +58,7 @@
this.tx = tx;
this.obj = obj;
this.isNew = isNew ? Boolean.TRUE : Boolean.FALSE;
- initCld(tx);
+ init(tx);
}
public RuntimeObject(final Object obj, final Identity identity, final TransactionImpl tx, final boolean isNew)
@@ -59,20 +67,18 @@
this.obj = obj;
this.identity = identity;
this.isNew = isNew ? Boolean.TRUE : Boolean.FALSE;
- initCld(tx);
+ init(tx);
}
- public RuntimeObject(final Object obj, final Identity oid, final ClassDescriptor cld, final boolean isNew, final boolean isProxy)
+ public RuntimeObject(final PersistenceBrokerInternal broker, final Object obj, final Identity oid,
+ final ClassDescriptor cld, final boolean isNew)
{
this.tx = null;
this.obj = obj;
this.identity = oid;
this.isNew = isNew ? Boolean.TRUE : Boolean.FALSE;
this.cld = cld;
- if(isProxy)
- {
- this.handler = ProxyHelper.getIndirectionHandler(obj);
- }
+ this.handler = broker.getProxyFactory().getIndirectionHandler(obj);
}
/*
@@ -80,9 +86,10 @@
best performance, thus create Identity object only if needed
and do 'is new object' check only if needed.
*/
- private void initCld(final TransactionImpl tx)
+ private void init(final TransactionImpl tx)
{
- final IndirectionHandler handler = ProxyHelper.getIndirectionHandler(obj);
+ final PersistenceBrokerInternal pb = tx.getBrokerInternal();
+ final IndirectionHandler handler = pb.getProxyFactory().getIndirectionHandler(obj);
if(handler != null)
{
this.handler = handler;
@@ -90,22 +97,22 @@
identity = handler.getIdentity();
if(handler.alreadyMaterialized())
{
- cld = tx.getBroker().getClassDescriptor(handler.getRealSubject().getClass());
+ cld = pb.getClassDescriptor(handler.getRealSubject().getClass());
}
else
{
- cld = tx.getBroker().getClassDescriptor(identity.getObjectsRealClass());
+ cld = pb.getClassDescriptor(identity.getObjectsRealClass());
}
}
else
{
- cld = tx.getBroker().getClassDescriptor(obj.getClass());
+ cld = pb.getClassDescriptor(obj.getClass());
}
}
void doIsNewObjectCheck(final TransactionImpl tx)
{
- boolean isNew = tx.isTransient(cld, obj, null);
+ boolean isNew = !isProxy() && tx.isTransient(cld, obj, getIdentity());
this.isNew = isNew ? Boolean.TRUE : Boolean.FALSE;
}
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionExt.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionExt.java?view=diff&rev=469559&r1=469558&r2=469559
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionExt.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionExt.java Tue Oct 31 09:08:15 2006
@@ -126,36 +126,38 @@
*/
public void setOrdering(boolean ordering);
-// /**
-// * Returns whether or not the persistent method calls determine
-// * the persistent object order on commit.
-// *
-// * @see #setNoteUserOrder(boolean)
-// */
-// public boolean isNoteUserOrder();
-//
-// /**
-// * If <em>true</em> the order of persisting method calls like
-// * <br/> - {@link org.odmg.Transaction#lock(Object, int)}).
-// * <br/> - {@link org.odmg.Database#deletePersistent(Object)}).
-// * <br/> - {@link org.odmg.Database#makePersistent(Object)})
-// * determine the order of objects before commit.
-// * <br/>
-// * If <em>false</em> the ordering was determined by OJB's internal
-// * method calls and user calls.
-// * <br/>
-// * However it's possible to set this value as a global property
-// * for all transactions using {@link ImplementationExt#setNoteUserOrder(boolean)}.
-// * <p/>
-// * <strong>NOTE:</strong> If OJB's ordering algorithm (see
-// * {@link #setOrdering(boolean)}) is enabled, the
-// * order of objects may change on commit.
-// *
-// * @param noteUserOrder If <em>true</em> the order of persisting
-// * method calls determine the order of objects.
-// * @see ImplementationExt#setNoteUserOrder(boolean)
-// */
-// public void setNoteUserOrder(boolean noteUserOrder);
+ /**
+ * If returns <em>true</em> transient objects will be detected in an
+ * optimized and performant way.
+ *
+ * @see #setOptimizedTransientObjectDetection(boolean)
+ * @return The mode setting.
+ */
+ public boolean isOptimizedTransientObjectDetection();
+
+ /**
+ * The detection of transient objects could be costly (e.g. if a select of ID in
+ * database is used to check if object already exists) we do: <br/>
+ * a. Check if the object {@link org.apache.ojb.broker.Identity} mark the
+ * specified object as transient. If this is <em>false</em> the object has populated
+ * primary key fields, if <em>true</em> at least one PK field is <em>null</em>
+ * and the object is transient.
+ * <br/>
+ * b. Then we check if the object was already registered in current transaction.
+ * if <em>true</em> we can ask for transient state.
+ * <br/>
+ * c. If the primary key fields are defined/mapped as <em>autoIncrement</em> fields and
+ * <em>optimizedTransientObjectDetection</em> is enabled OJB assume that the object
+ * is persistent.
+ * If the PK fields are not autoIncrement fields or the optimized detection is
+ * disabled a database <em>exists object</em> query is performed to check if the
+ * object is persistent or transient.
+ * <br/>
+ *
+ * @param optimizedTransientObjectDetection If <em>true</em> enable the optimized transient
+ * object detection for this transaction.
+ */
+ public void setOptimizedTransientObjectDetection(boolean optimizedTransientObjectDetection);
/**
* Checks if the object with the given {@link org.apache.ojb.broker.Identity}
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionImpl.java?view=diff&rev=469559&r1=469558&r2=469559
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/TransactionImpl.java Tue Oct 31 09:08:15 2006
@@ -38,7 +38,7 @@
import org.apache.ojb.broker.core.proxy.CollectionProxyListener;
import org.apache.ojb.broker.core.proxy.IndirectionHandler;
import org.apache.ojb.broker.core.proxy.MaterializationListener;
-import org.apache.ojb.broker.core.proxy.ProxyHelper;
+import org.apache.ojb.broker.core.proxy.ProxyFactory;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.CollectionDescriptor;
import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
@@ -80,6 +80,7 @@
private boolean impliciteWriteLocks;
private boolean implicitLocking;
private boolean ordering;
+ private boolean optimizedTransientObjectDetection;
/**
* The status of the current transaction, as specified by the
@@ -137,6 +138,7 @@
this.impliciteWriteLocks = implementation.isImpliciteWriteLocks();
this.implicitLocking = implementation.isImplicitLocking();
this.ordering = implementation.isOrdering();
+ this.optimizedTransientObjectDetection = implementation.isOptimizedTransientObjectDetection();
// assign a uniqe id to this tx
txGUID = guid.next();
curDB = implementation.getCurrentDatabase();
@@ -367,12 +369,7 @@
*/
if(mod != null)
{
- // only use real objects, no proxy instances
- Object realObj = rtObject.getObjMaterialized();
- if(realObj != null)
- {
- mod.refreshObjectIfNeeded(realObj);
- }
+ mod.refreshObjectIfNeeded(rtObject.getObj());
}
}
}
@@ -647,18 +644,14 @@
void markDirty(RuntimeObject rt)
{
- ObjectEnvelope otw = objectEnvelopeTable.get(rt.getIdentity(), rt.getObj(), rt.isNew());
+ ObjectEnvelope otw = objectEnvelopeTable.get(rt);
otw.refreshObjectIfNeeded(rt.getObj());
otw.setModificationState(otw.getModificationState().markDirty());
}
void markPersistent(RuntimeObject rtObj)
{
- ObjectEnvelope oe = objectEnvelopeTable.getByIdentity(rtObj.getIdentity());
- if(oe == null)
- {
- oe = objectEnvelopeTable.get(rtObj.getIdentity(), rtObj.getObj(), rtObj.isNew());
- }
+ ObjectEnvelope oe = objectEnvelopeTable.get(rtObj);
if(oe.needsDelete())
{
oe.setModificationState(oe.getModificationState().markNew());
@@ -969,7 +962,7 @@
if ((envelope == null))
{
// register object itself
- envelope = objectEnvelopeTable.get(rtObject.getIdentity(), rtObject.getObj(), rtObject.isNew());
+ envelope = objectEnvelopeTable.register(rtObject);
}
else
{
@@ -1003,15 +996,14 @@
{
if (implicitLocking)
{
- Iterator i = cld.getObjectReferenceDescriptors(true).iterator();
- while (i.hasNext())
+ List ords = cld.getObjectReferenceDescriptors(true);
+ for (int i = 0; i < ords.size(); i++)
{
- ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) i.next();
+ ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) ords.get(i);
Object refObj = rds.getPersistentField().get(sourceObject);
if (refObj != null)
{
- boolean isProxy = ProxyHelper.isProxy(refObj);
- RuntimeObject rt = isProxy ? new RuntimeObject(refObj, this, false) : new RuntimeObject(refObj, this);
+ RuntimeObject rt = new RuntimeObject(refObj, this);
internalLockRegister(rt, lockMode, cascade);
}
}
@@ -1022,14 +1014,15 @@
{
if (implicitLocking)
{
- Iterator i = cld.getCollectionDescriptors(true).iterator();
- while (i.hasNext())
+ ProxyFactory proxyFactory = getBrokerInternal().getProxyFactory();
+ List cdss = cld.getCollectionDescriptors(true);
+ for (int i = 0; i < cdss.size(); i++)
{
- CollectionDescriptor cds = (CollectionDescriptor) i.next();
+ CollectionDescriptor cds = (CollectionDescriptor) cdss.get(i);
Object col = cds.getPersistentField().get(sourceObject);
if (col != null)
{
- CollectionProxy proxy = ProxyHelper.getCollectionProxy(col);
+ CollectionProxy proxy = proxyFactory.getCollectionProxy(col);
if (proxy != null)
{
if (!proxy.isLoaded())
@@ -1050,7 +1043,7 @@
RuntimeObject rt = new RuntimeObject(item, this);
if (rt.isProxy())
{
- IndirectionHandler handler = ProxyHelper.getIndirectionHandler(item);
+ IndirectionHandler handler = proxyFactory.getIndirectionHandler(item);
if (!handler.alreadyMaterialized())
{
registerToIndirectionHandler(handler);
@@ -1117,7 +1110,7 @@
}
}
ClassDescriptor cld = getBroker().getClassDescriptor(materializedObject.getClass());
- RuntimeObject rt = new RuntimeObject(materializedObject, oid, cld, false, false);
+ RuntimeObject rt = new RuntimeObject(getBrokerInternal(), materializedObject, oid, cld, false);
lockAndRegister(rt, Transaction.READ, isImplicitLocking());
}
catch (Throwable t)
@@ -1320,9 +1313,7 @@
}
else
{
- Identity oid = getBroker().serviceIdentity().buildIdentity(o);
- ClassDescriptor cld = getBroker().getClassDescriptor(ProxyHelper.getRealClass(o));
- RuntimeObject rt = new RuntimeObject(o, oid, cld, false, ProxyHelper.isProxy(o));
+ RuntimeObject rt = new RuntimeObject(o, this, false);
lockAndRegister(rt, Transaction.READ, isImplicitLocking());
}
}
@@ -1387,46 +1378,43 @@
}
/**
- * Detect new objects.
+ * This method help to detect transient/new objects.
+ *
+ * @param obj The non proxy object to detect.
+ * @param oid The {@link org.apache.ojb.broker.Identity} of the object.
+ * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of
+ * the object or <em>null</em>.
*/
protected boolean isTransient(ClassDescriptor cld, Object obj, Identity oid)
{
// if the Identity is transient we assume a non-persistent object
- boolean isNew = oid != null && oid.isTransient();
+ boolean isNew = oid.isTransient();
/*
- detection of new objects is costly (select of ID in DB to check if object
+ detection of transient objects is costly (select of ID in DB to check if object
already exists) we do:
- a. check if the object has nullified PK field
- b. check if the object is already registered
- c. lookup from cache and if not found, last option select on DB
+ a. check if the object identity mark the specified object as transient
+ b. lookup from cache
+ c. and if not found, last option select on DB
*/
if(!isNew)
{
- final PersistenceBroker pb = getBroker();
- if(cld == null)
+ ObjectEnvelope mod = objectEnvelopeTable.getByIdentity(oid);
+ if(mod != null)
{
- cld = pb.getClassDescriptor(obj.getClass());
+ // already registered object, use current state
+ isNew = mod.needsInsert();
}
- isNew = pb.serviceBrokerHelper().hasNullPKField(cld, obj);
- if(!isNew)
+ else if(!optimizedTransientObjectDetection || cld.getAutoIncrementFields().length < 1)
{
- if(oid == null)
- {
- oid = pb.serviceIdentity().buildIdentity(cld, obj);
- }
- final ObjectEnvelope mod = objectEnvelopeTable.getByIdentity(oid);
- if(mod != null)
+ PersistenceBrokerInternal pb = getBrokerInternal();
+ if(cld == null)
{
- // already registered object, use current state
- isNew = mod.needsInsert();
- }
- else
- {
- // if object was found cache, assume it's old
- // else make costly check against the DB
- isNew = pb.serviceObjectCache().lookup(oid) == null
- && !pb.serviceBrokerHelper().doesExist(cld, oid, obj);
+ cld = pb.getClassDescriptor(obj.getClass());
}
+ // if object was found cache, assume it's old
+ // else make costly check against the DB
+ isNew = pb.serviceObjectCache().lookup(oid) == null
+ && !pb.serviceBrokerHelper().doesExist(cld, oid, obj);
}
}
return isNew;
@@ -1548,6 +1536,16 @@
public void setOrdering(boolean ordering)
{
this.ordering = ordering;
+ }
+
+ public boolean isOptimizedTransientObjectDetection()
+ {
+ return optimizedTransientObjectDetection;
+ }
+
+ public void setOptimizedTransientObjectDetection(boolean optimizedTransientObjectDetection)
+ {
+ this.optimizedTransientObjectDetection = optimizedTransientObjectDetection;
}
protected void finalize() throws Throwable
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.