You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2006/10/31 18:08:17 UTC
svn commit: r469559 -
/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/odmg/
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:thma@apache.org">Thomas Mahler<a>
- * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird</a>
- * @author <a href="mailto:armin@codeAuLait.de">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:mattbaird@yahoo.com">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:arminw@apache.org">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
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org