Author: arminw
Date: Tue Oct 31 09:09:20 2006
New Revision: 469563
URL: http://svn.apache.org/viewvc?view=rev&rev=469563
Log:
odmg-api performance improvement
Modified:
db/ojb/trunk/src/java/org/apache/ojb/odmg/DatabaseImpl.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/ImplementationExt.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/ImplementationImpl.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/NarrowTransaction.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelope.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/RuntimeObject.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionExt.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionImpl.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/oql/OQLQueryImpl.java
Modified: db/ojb/trunk/src/java/org/apache/ojb/odmg/DatabaseImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/DatabaseImpl.java?view=diff&rev=469563&r1=469562&r2=469563
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/DatabaseImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/DatabaseImpl.java Tue Oct 31 09:09:20 2006
@@ -287,9 +287,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());
}
/**
@@ -316,6 +315,5 @@
}
RuntimeObject rt = new RuntimeObject(object, tx);
tx.deletePersistent(rt);
-// tx.moveToLastInOrderList(rt.getIdentity());
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/odmg/ImplementationExt.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/ImplementationExt.java?view=diff&rev=469563&r1=469562&r2=469563
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/ImplementationExt.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/ImplementationExt.java Tue Oct 31 09:09:20 2006
@@ -29,24 +29,24 @@
*/
public interface ImplementationExt extends Implementation
{
- /**
- * The used collection type class returned by OQL queries.
- *
- * @see org.apache.ojb.odmg.oql.EnhancedOQLQuery#execute()
- * @see org.odmg.OQLQuery#execute()
- * @return The collection class type
- */
- public Class getOqlCollectionClass();
-
- /**
- * Set the used collection type class returned by OQL queries.
- * <p/>
- * NOTE: Each specified class must implement interface {@link org.apache.ojb.broker.ManageableCollection}
- * to work proper with OJB.
- *
- * @param oqlCollectionClass The collection class used in OQL queries.
- */
- public void setOqlCollectionClass(Class oqlCollectionClass);
+// /**
+// * The used collection type class returned by OQL queries.
+// *
+// * @see org.apache.ojb.odmg.oql.EnhancedOQLQuery#execute()
+// * @see org.odmg.OQLQuery#execute()
+// * @return The collection class type
+// */
+// public Class getOqlCollectionClass();
+//
+// /**
+// * Set the used collection type class returned by OQL queries.
+// * <p/>
+// * NOTE: Each specified class must implement interface {@link org.apache.ojb.broker.ManageableCollection}
+// * to work proper with OJB.
+// *
+// * @param oqlCollectionClass The collection class used in OQL queries.
+// */
+// public void setOqlCollectionClass(Class oqlCollectionClass);
/**
* If the OJB implicit locking feature (see {@link TransactionExt#setImplicitLocking(boolean)}) is
@@ -135,48 +135,43 @@
public void setOrdering(boolean ordering);
/**
- * Return OJB's odmg-specific {@link org.apache.ojb.odmg.locking.LockManager}.
+ * If returns <em>true</em> transient objects will be detected in an
+ * optimized and performant way.
+ *
+ * @see #setOptimizedTransientObjectDetection(boolean)
+ * @return The mode setting.
*/
- public LockManager getLockManager();
+ public boolean isOptimizedTransientObjectDetection();
-// /**
-// * 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);
+ /**
+ * 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);
-// /**
-// * 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);
+ /**
+ * Return OJB's odmg-specific {@link org.apache.ojb.odmg.locking.LockManager}.
+ */
+ public LockManager getLockManager();
// /**
// * If set <em>true</em> the odmg implementation do it's best to find out the user intension, if set
Modified: db/ojb/trunk/src/java/org/apache/ojb/odmg/ImplementationImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/ImplementationImpl.java?view=diff&rev=469563&r1=469562&r2=469563
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/ImplementationImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/ImplementationImpl.java Tue Oct 31 09:09:20 2006
@@ -44,10 +44,6 @@
/**
* Default implementation of the {@link Implementation} 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 ImplementationImpl implements ImplementationExt
@@ -59,12 +55,12 @@
private LockManager lockManager;
private org.apache.ojb.broker.OJB ojb;
- private Class oqlCollectionClass;
private boolean impliciteWriteLocks;
private boolean implicitLocking;
private boolean implicitLockingBackward;
private boolean ordering;
private boolean managed = false;
+ private boolean optimizedTransientObjectDetection;
/**
* Creates a new implementation instance. Please do not use this directly
@@ -365,22 +361,6 @@
}
/**
- * @see ImplementationExt#getOqlCollectionClass()
- */
- public Class getOqlCollectionClass()
- {
- return oqlCollectionClass;
- }
-
- /**
- * @see ImplementationExt#setOqlCollectionClass(Class)
- */
- public void setOqlCollectionClass(Class oqlCollectionClass)
- {
- this.oqlCollectionClass = oqlCollectionClass;
- }
-
- /**
* @see ImplementationExt#setImpliciteWriteLocks(boolean)
*/
public void setImpliciteWriteLocks(boolean impliciteWriteLocks)
@@ -406,6 +386,16 @@
this.ordering = ordering;
}
+ public boolean isOptimizedTransientObjectDetection()
+ {
+ return optimizedTransientObjectDetection;
+ }
+
+ public void setOptimizedTransientObjectDetection(boolean optimizedTransientObjectDetection)
+ {
+ this.optimizedTransientObjectDetection = optimizedTransientObjectDetection;
+ }
+
/**
* Allow to use method {@link #setImplicitLocking(boolean)} in the same way
* as before version 1.0.4 - if set 'true', recommended setting is 'false'.
@@ -434,7 +424,7 @@
.append("implicitLocking", isImplicitLocking())
.append("implicitWriteLocks", isImpliciteWriteLocks())
.append("ordering", isOrdering())
- .append("oqlCollectionClass", getOqlCollectionClass())
+ //.append("oqlCollectionClass", getOqlCollectionClass())
.append("txManager", getTxManager())
.append("lockManager", getLockManager())
.toString();
Modified: db/ojb/trunk/src/java/org/apache/ojb/odmg/NarrowTransaction.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/NarrowTransaction.java?view=diff&rev=469563&r1=469562&r2=469563
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/NarrowTransaction.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/NarrowTransaction.java Tue Oct 31 09:09:20 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/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelope.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelope.java?view=diff&rev=469563&r1=469562&r2=469563
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelope.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelope.java Tue Oct 31 09:09:20 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.ProxyFactory;
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,20 +100,35 @@
this.linkEntryList = new ArrayList();
this.buffer = buffer;
this.oid = oid;
+ PersistenceBrokerInternal pb = getBroker();
+ myObj = obj;
// TODO: do we really need to materialize??
- myObj = getProxyFactory().getRealObject(obj);
+ realObject = pb.getProxyFactory().getRealObject(obj);
prepareInitialState(isNewObject);
- beforeImage = buildObjectImage(getBroker(), isNewObject);
+ beforeImage = buildObjectImage(isNewObject);
}
- private ProxyFactory getProxyFactory()
+ ObjectEnvelope(ObjectEnvelopeTable buffer, Identity oid, ClassDescriptor cld, Object obj, boolean isNewObject)
{
- return buffer.getTransaction().getBrokerInternal().getProxyFactory();
+ 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??
+ realObject = pb.getProxyFactory().getRealObject(obj);
+ prepareInitialState(isNewObject);
+ beforeImage = buildObjectImage(isNewObject);
}
public PersistenceBrokerInternal getBroker()
{
- return buffer.getTransaction().getBrokerInternal();
+ if(broker == null)
+ {
+ broker = buffer.getTransaction().getBrokerInternal();
+ }
+ return broker;
}
TransactionImpl getTx()
@@ -125,7 +145,7 @@
{
if(beforeImage == null)
{
- beforeImage = buildObjectImage(getBroker());
+ beforeImage = buildObjectImage(false);
}
return beforeImage;
}
@@ -134,7 +154,7 @@
{
if(currentImage == null)
{
- currentImage = buildObjectImage(getBroker(), needsInsert());
+ currentImage = buildObjectImage(needsInsert());
}
return currentImage;
}
@@ -146,6 +166,7 @@
*/
public void cleanup(boolean reuse, boolean wasInsert)
{
+ broker = null;
if(currentImage != null)
{
performImageCleanup(currentImage, reuse);
@@ -157,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();
@@ -164,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);
}
}
@@ -183,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,
@@ -200,7 +231,7 @@
{
if(beforeImage == null)
{
- beforeImage = buildObjectImage(getBroker(), wasNewObject);
+ beforeImage = buildObjectImage(wasNewObject);
}
}
currentImage = null;
@@ -273,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 getProxyFactory().getRealObject(myObj);
+ if(realObject == null)
+ {
+ realObject = getBroker().getProxyFactory().getRealObject(getObject());
+ }
+ return realObject;
}
public void refreshObjectIfNeeded(Object obj)
@@ -290,6 +328,7 @@
if(this.myObj != obj)
{
this.myObj = obj;
+ this.realObject = null;
}
}
@@ -356,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);
@@ -381,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)
@@ -393,9 +424,9 @@
*/
if(!rds.isSuperReferenceDescriptor())
{
- Object referenceObject = rds.getPersistentField().get(myObj);
+ Object referenceObject = rds.getPersistentField().get(getRealObject());
- IndirectionHandler handler = getProxyFactory().getIndirectionHandler(referenceObject);
+ IndirectionHandler handler = getBroker().getProxyFactory().getIndirectionHandler(referenceObject);
/*
arminw:
if object was serialized and anonymous FK are used in the main object, the FK
@@ -405,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);
@@ -426,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);
}
@@ -524,7 +549,6 @@
public boolean isDeleted(Identity id)
{
ObjectEnvelope envelope = buffer.getByIdentity(id);
-
return (envelope != null && envelope.needsDelete());
}
@@ -620,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);
}
}
@@ -642,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()
@@ -698,7 +724,12 @@
ClassDescriptor getClassDescriptor()
{
- return getBroker().getClassDescriptor(getProxyFactory().getRealClass(getObject()));
+ if(cld == null)
+ {
+ PersistenceBrokerInternal broker = getBroker();
+ cld = broker.getClassDescriptor(broker.getProxyFactory().getRealClass(getObject()));
+ }
+ return cld;
}
void addLinkOneToOne(ObjectReferenceDescriptor ord, boolean unlink)
@@ -735,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);
@@ -770,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/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java?view=diff&rev=469563&r1=469562&r2=469563
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java Tue Oct 31 09:09:20 2006
@@ -22,7 +22,6 @@
import org.apache.commons.lang.ArrayUtils;
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.ProxyFactory;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.CollectionDescriptor;
@@ -71,7 +70,6 @@
* we are done.
* </ol>
*
- * @author Gerhard Grosse
* @version $Id$
* @since Nov 15, 2004
*/
@@ -257,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);
}
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java?view=diff&rev=469563&r1=469562&r2=469563
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java Tue Oct 31 09:09:20 2006
@@ -18,13 +18,15 @@
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;
import org.apache.commons.lang.builder.ToStringStyle;
-import org.apache.commons.lang.SystemUtils;
import org.apache.ojb.broker.Identity;
import org.apache.ojb.broker.OJBRuntimeException;
import org.apache.ojb.broker.OptimisticLockException;
@@ -49,6 +51,8 @@
/**
* Manages all ObjectEnvelopes included by a transaction.
* Performs commit, and rollack operations on all included Envelopes.
+ *
+ * @version $Id: $
*/
class ObjectEnvelopeTable
{
@@ -61,7 +65,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();
@@ -262,10 +266,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
@@ -285,10 +285,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()))
@@ -306,12 +306,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())
{
@@ -406,23 +406,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);
}
/**
@@ -431,19 +454,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 oe = getByIdentity(oid);
+ if(oe == null)
+ {
+ oe = register(oid, object, isNew);
+ }
+ return oe;
+ }
+
+ public ObjectEnvelope get(RuntimeObject rtObject)
+ //public ObjectEnvelope registerIfNeeded(Object object, boolean isNew)
{
- ObjectEnvelope result = getByIdentity(oid);
- if(result == null)
+ ObjectEnvelope oe = getByIdentity(rtObject.getIdentity());
+ 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(rtObject);
}
- return result;
+ 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()
{
@@ -540,29 +579,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 = getTransaction()
- .getBrokerInternal().getProxyFactory().getIndirectionHandler(depObj);
+ IndirectionHandler handler = pb.getProxyFactory().getIndirectionHandler(depObj);
// if the object is not materialized, nothing has changed
if(handler == null || handler.alreadyMaterialized())
{
@@ -598,7 +637,7 @@
for(int i = 0; i < descriptor.size(); i++)
{
CollectionDescriptor col = (CollectionDescriptor) descriptor.get(i);
- Object collOrArray = col.getPersistentField().get(source.getObject());
+ Object collOrArray = col.getPersistentField().get(source.getRealObject());
CollectionProxy proxy = pb.getProxyFactory().getCollectionProxy(collOrArray);
/*
on insert we perform only materialized collection objects. This should be
@@ -640,12 +679,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)
@@ -670,7 +709,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);
@@ -686,7 +725,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);
@@ -710,7 +749,7 @@
{
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());
Iterator it = null;
if(collOrArray != null)
{
Modified: db/ojb/trunk/src/java/org/apache/ojb/odmg/RuntimeObject.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/RuntimeObject.java?view=diff&rev=469563&r1=469562&r2=469563
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/RuntimeObject.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/RuntimeObject.java Tue Oct 31 09:09:20 2006
@@ -25,7 +25,6 @@
* 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 PersistenceBrokerInternal broker, 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 = broker.getProxyFactory().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 = tx.getBrokerInternal().getProxyFactory().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/trunk/src/java/org/apache/ojb/odmg/TransactionExt.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionExt.java?view=diff&rev=469563&r1=469562&r2=469563
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionExt.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionExt.java Tue Oct 31 09:09:20 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/trunk/src/java/org/apache/ojb/odmg/TransactionImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionImpl.java?view=diff&rev=469563&r1=469562&r2=469563
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionImpl.java Tue Oct 31 09:09:20 2006
@@ -58,7 +58,6 @@
* Implementation of Transaction for {@link org.odmg.Transaction}.
*
* @version $Id$
- *
*/
public class TransactionImpl
implements Transaction, MaterializationListener, CollectionProxyListener, TransactionExt
@@ -76,6 +75,7 @@
private boolean impliciteWriteLocks;
private boolean implicitLocking;
private boolean ordering;
+ private boolean optimizedTransientObjectDetection;
/**
* The status of the current transaction, as specified by the
@@ -125,6 +125,7 @@
/**
* Creates new Transaction
+ *
* @param implementation The odmg Implementation class
*/
public TransactionImpl(ImplementationImpl implementation)
@@ -133,6 +134,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();
@@ -171,7 +173,7 @@
private void checkForDB()
{
- if (curDB == null || !curDB.isOpen())
+ if(curDB == null || !curDB.isOpen())
{
log.error("Transaction without a associated open Database.");
throw new TransactionAbortedExceptionOJB(
@@ -183,7 +185,8 @@
* Determine whether the transaction is open or not. A transaction is open if
* a call has been made to <code>begin</code> , but a subsequent call to
* either <code>commit</code> or <code>abort</code> has not been made.
- * @return True if the transaction is open, otherwise false.
+ *
+ * @return True if the transaction is open, otherwise false.
*/
public boolean isOpen()
{
@@ -196,11 +199,11 @@
private void checkOpen()
{
- if (!isOpen())
+ if(!isOpen())
{
throw new TransactionNotInProgressException(
"Transaction was not open, call tx.begin() before perform action, current status is: " +
- TxUtil.getStatusString(getStatus()));
+ TxUtil.getStatusString(getStatus()));
}
}
@@ -222,15 +225,14 @@
* no effect if the object's current lock is already at or above that level of
* lock mode.
*
- * @param obj object to acquire a lock on.
- * @param lockMode lock mode to acquire. The lock modes
+ * @param obj object to acquire a lock on.
+ * @param lockMode lock mode to acquire. The lock modes
* are <code>READ</code> , <code>UPGRADE</code> , and <code>WRITE</code> .
- *
- * @exception LockNotGrantedException Description of Exception
+ * @throws LockNotGrantedException Description of Exception
*/
public void lock(Object obj, int lockMode) throws LockNotGrantedException
{
- if (log.isDebugEnabled()) log.debug("lock object was called on tx " + this + ", object is " + obj.toString());
+ if(log.isDebugEnabled()) log.debug("lock object was called on tx " + this + ", object is " + obj.toString());
checkOpen();
RuntimeObject rtObject = new RuntimeObject(obj, this);
lockAndRegister(rtObject, lockMode, isImplicitLocking());
@@ -275,7 +277,7 @@
(e.g. the odmg collection implementations use this interface)
with current pc-configuration and OJB's tx-manager.
*/
- getImplementation().prepareOJBBaseInstance(rtObject.getObj());
+ getImplementation().prepareOJBBaseInstance(objectToRegister);
/*
if the object is a Proxy there are two options:
1. The proxies real subject has already been materialized:
@@ -300,7 +302,7 @@
{
throw new OJBRuntimeException("Unexpected error, expect an proxy object as indicated: " + rtObject);
}
- if (handler.alreadyMaterialized())
+ if(handler.alreadyMaterialized())
{
objectToRegister = handler.getRealSubject();
}
@@ -322,43 +324,43 @@
// to lock the referenced objects too
internalLockRegisterReferences(rtObject.getCld(), rtObject.getObjMaterialized(), lockMode, cascade);
}
- try
- {
- // perform the lock on the object
- // we don't need to lock new objects
- if(!rtObject.isNew())
+ try
{
+ // perform the lock on the object
+ // we don't need to lock new objects
+ if(!rtObject.isNew())
+ {
internalSingleLock(rtObject.getCld(), rtObject.getIdentity(), lockMode);
- }
- // after we locked the object, register it to detect status and changes while tx
+ }
+ // after we locked the object, register it to detect status and changes while tx
internalSingleRegister(rtObject, lockMode);
- }
- catch (Throwable t)
- {
- //log.error("Locking of obj " + rtObject.getIdentity() + " failed", t);
- // if registering of object fails release lock on object, because later we don't
- // get a change to do this.
- implementation.getLockManager().releaseLock(this, rtObject.getIdentity());
- if(t instanceof LockNotGrantedException)
- {
- throw (LockNotGrantedException) t;
}
- else
+ catch(Throwable t)
{
- log.error("Unexpected failure while locking", t);
- throw new LockNotGrantedException("Locking failed for "
- + rtObject.getIdentity()+ ", nested exception is: [" + t.getClass().getName()
- + ": " + t.getMessage() + "]");
+ //log.error("Locking of obj " + rtObject.getIdentity() + " failed", t);
+ // if registering of object fails release lock on object, because later we don't
+ // get a change to do this.
+ implementation.getLockManager().releaseLock(this, rtObject.getIdentity());
+ if(t instanceof LockNotGrantedException)
+ {
+ throw (LockNotGrantedException) t;
+ }
+ else
+ {
+ log.error("Unexpected failure while locking", t);
+ throw new LockNotGrantedException("Locking failed for "
+ + rtObject.getIdentity() + ", nested exception is: [" + t.getClass().getName()
+ + ": " + t.getMessage() + "]");
+ }
}
- }
if(cascade)
{
// perform locks and register 1:n and m:n references
// If implicit locking is used, we have to use the materialized main object
// to lock the referenced objects too
internalLockRegisterCollections(rtObject.getCld(), rtObject.getObjMaterialized(), lockMode, cascade);
- }
- }
+ }
+ }
}
else
{
@@ -369,12 +371,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());
}
}
}
@@ -383,38 +380,37 @@
* Only lock the specified object, represented by
* the {@link RuntimeObject} instance.
*
- * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor}
+ * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor}
* of the object to acquire a lock on.
- * @param oid The {@link org.apache.ojb.broker.Identity} of the object to lock.
- * @param lockMode lock mode to acquire. The lock modes
+ * @param oid The {@link org.apache.ojb.broker.Identity} of the object to lock.
+ * @param lockMode lock mode to acquire. The lock modes
* are <code>READ</code> , <code>UPGRADE</code> , and <code>WRITE</code>.
- *
- * @exception LockNotGrantedException Description of Exception
+ * @throws LockNotGrantedException Description of Exception
*/
void internalSingleLock(final ClassDescriptor cld, final Identity oid, final int lockMode) throws LockNotGrantedException
{
- if (cld.isAcceptLocks())
+ if(cld.isAcceptLocks())
{
LockManager lm = implementation.getLockManager();
- if (lockMode == Transaction.READ)
+ if(lockMode == Transaction.READ)
{
- if (log.isDebugEnabled()) log.debug("Do READ lock on object: " + oid);
+ if(log.isDebugEnabled()) log.debug("Do READ lock on object: " + oid);
if(!lm.readLock(this, oid, cld))
{
throw new LockNotGrantedException("Can not lock for READ: " + oid);
}
}
- else if (lockMode == Transaction.WRITE)
+ else if(lockMode == Transaction.WRITE)
{
- if (log.isDebugEnabled()) log.debug("Do WRITE lock on object: " + oid);
+ if(log.isDebugEnabled()) log.debug("Do WRITE lock on object: " + oid);
if(!lm.writeLock(this, oid, cld))
{
throw new LockNotGrantedException("Can not lock for WRITE: " + oid);
}
}
- else if (lockMode == Transaction.UPGRADE)
+ else if(lockMode == Transaction.UPGRADE)
{
- if (log.isDebugEnabled()) log.debug("Do UPGRADE lock on object: " + oid);
+ if(log.isDebugEnabled()) log.debug("Do UPGRADE lock on object: " + oid);
if(!lm.upgradeLock(this, oid, cld))
{
throw new LockNotGrantedException("Can not lock for UPGRADE: " + oid);
@@ -423,7 +419,7 @@
}
else
{
- if (log.isDebugEnabled())
+ if(log.isDebugEnabled())
{
log.debug("Class '" + cld.getClassNameOfObject() + "' doesn't accept locks" +
" (accept-locks=false) when implicite locked, so OJB skip this object: " + oid);
@@ -452,9 +448,9 @@
arminw:
if broker isn't in PB-tx, start tx
*/
- if (!getBroker().isInTransaction())
+ if(!getBroker().isInTransaction())
{
- if (log.isDebugEnabled()) log.debug("call beginTransaction() on PB instance");
+ if(log.isDebugEnabled()) log.debug("call beginTransaction() on PB instance");
broker.setManaged(implementation.isManaged());
broker.beginTransaction();
}
@@ -516,7 +512,7 @@
/**
* MBAIRD: Be nice and close the table to release all refs
*/
- if (log.isDebugEnabled())
+ if(log.isDebugEnabled())
log.debug("Close Transaction and release current PB " + broker + " on tx " + this);
txStatus = Status.STATUS_NO_TRANSACTION;
// remove current thread from LocalTxManager
@@ -532,8 +528,8 @@
*/
protected void refresh()
{
- if (log.isDebugEnabled()) log.debug("Refresh this transaction for reuse: " + this);
- // we reuse ObjectEnvelopeTable instance
+ if(log.isDebugEnabled()) log.debug("Refresh this transaction for reuse: " + this);
+ // we reuse ObjectEnvelopeTable instance
objectEnvelopeTable.prepareForUse();
// clear the temporary used named roots map
// we should do that, because same tx instance
@@ -552,15 +548,15 @@
*/
public void checkpoint()
{
- if (log.isDebugEnabled()) log.debug("Checkpoint was called, commit changes hold locks on tx " + this);
+ if(log.isDebugEnabled()) log.debug("Checkpoint was called, commit changes hold locks on tx " + this);
try
{
checkOpen();
doWriteObjects(true);
// do commit on PB
- if (hasBroker() && broker.isInTransaction()) broker.commitTransaction();
+ if(hasBroker() && broker.isInTransaction()) broker.commitTransaction();
}
- catch (Throwable t)
+ catch(Throwable t)
{
log.error("Checkpoint call failed, do abort transaction", t);
txStatus = Status.STATUS_MARKED_ROLLBACK;
@@ -581,7 +577,7 @@
*/
public void flush()
{
- if (log.isDebugEnabled())
+ if(log.isDebugEnabled())
{
log.debug("Flush was called - write changes to database, do not commit, hold locks on tx " + this);
}
@@ -591,7 +587,7 @@
checkOpen();
doWriteObjects(true);
}
- catch (Throwable t)
+ catch(Throwable t)
{
log.error("Calling method 'tx.flush()' failed", t);
txStatus = Status.STATUS_MARKED_ROLLBACK;
@@ -649,18 +645,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());
@@ -679,7 +671,7 @@
lockAndRegister(rt, Transaction.WRITE);
markPersistent(rt);
}
- catch (org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException ex)
+ catch(org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException ex)
{
log.error("Can't persist object: " + rt.getIdentity(), ex);
throw new org.odmg.ClassNotPersistenceCapableException(ex.getMessage());
@@ -699,22 +691,21 @@
* Upgrade the lock on the given object to the given lock mode. Method <code>
* tryLock</code> is the same as <code>lock</code> except it returns a boolean
* indicating whether the lock was granted instead of generating an exception.
- * @param obj Description of Parameter
- * @param lockMode Description of Parameter
- * @return Description of the Returned Value
- * </code>, <code>UPGRADE</code> , and <code>WRITE</code> .
+ *
+ * @param obj Description of Parameter
+ * @param lockMode Description of Parameter
* @return true if the lock has been acquired, otherwise false.
*/
public boolean tryLock(Object obj, int lockMode)
{
- if (log.isDebugEnabled()) log.debug("Try to lock object was called on tx " + this);
+ if(log.isDebugEnabled()) log.debug("Try to lock object was called on tx " + this);
checkOpen();
try
{
lock(obj, lockMode);
return true;
}
- catch (LockNotGrantedException ex)
+ catch(LockNotGrantedException ex)
{
return false;
}
@@ -751,11 +742,11 @@
{
if(needFullCommit())
{
- prepareCommit();
- checkForCommit();
+ prepareCommit();
+ checkForCommit();
- txStatus = Status.STATUS_COMMITTING;
- if (log.isDebugEnabled()) log.debug("Commit transaction " + this);
+ txStatus = Status.STATUS_COMMITTING;
+ if(log.isDebugEnabled()) log.debug("Commit transaction " + this);
}
// now do real commit on broker
if(hasBroker() && getBroker().isInTransaction()) getBroker().commitTransaction();
@@ -785,10 +776,10 @@
protected void checkForCommit()
{
// Never commit transaction that has been marked for rollback
- if (txStatus == Status.STATUS_MARKED_ROLLBACK)
+ if(txStatus == Status.STATUS_MARKED_ROLLBACK)
throw new TransactionAbortedExceptionOJB("Illegal tx-status: tx is already markedRollback");
// Don't commit if not prepared
- if (txStatus != Status.STATUS_PREPARED)
+ if(txStatus != Status.STATUS_PREPARED)
throw new IllegalStateException("Illegal tx-status: Do prepare commit before commit");
}
@@ -799,17 +790,17 @@
*
* @throws TransactionAbortedException if the transaction has been aborted
* for any reason.
- * @throws IllegalStateException Method called if transaction is
- * not in the proper state to perform this operation
+ * @throws IllegalStateException Method called if transaction is
+ * not in the proper state to perform this operation
* @throws TransactionNotInProgressException if the transaction is closed.
*/
protected void prepareCommit() throws TransactionAbortedException, LockNotGrantedException
{
- if (txStatus == Status.STATUS_MARKED_ROLLBACK)
+ if(txStatus == Status.STATUS_MARKED_ROLLBACK)
{
throw new TransactionAbortedExceptionOJB("Prepare Transaction: tx already marked for rollback");
}
- if (txStatus != Status.STATUS_ACTIVE)
+ if(txStatus != Status.STATUS_ACTIVE)
{
throw new IllegalStateException("Prepare Transaction: tx status is not 'active', status is " + TxUtil.getStatusString(txStatus));
}
@@ -819,7 +810,7 @@
doWriteObjects(false);
txStatus = Status.STATUS_PREPARED;
}
- catch (RuntimeException e)
+ catch(RuntimeException e)
{
log.error("Could not prepare for commit", e);
txStatus = Status.STATUS_MARKED_ROLLBACK;
@@ -837,7 +828,7 @@
/*
do nothing if already rolledback
*/
- if (txStatus == Status.STATUS_NO_TRANSACTION
+ if(txStatus == Status.STATUS_NO_TRANSACTION
|| txStatus == Status.STATUS_UNKNOWN
|| txStatus == Status.STATUS_ROLLEDBACK)
{
@@ -845,7 +836,7 @@
return;
}
// check status of tx
- if (txStatus != Status.STATUS_ACTIVE && txStatus != Status.STATUS_PREPARED &&
+ if(txStatus != Status.STATUS_ACTIVE && txStatus != Status.STATUS_PREPARED &&
txStatus != Status.STATUS_MARKED_ROLLBACK)
{
throw new IllegalStateException("Illegal state for abort call, state was '" + TxUtil.getStatusString(txStatus) + "'");
@@ -901,7 +892,7 @@
public synchronized void begin()
{
checkForBegin();
- if (log.isDebugEnabled()) log.debug("Begin transaction was called on tx " + this);
+ if(log.isDebugEnabled()) log.debug("Begin transaction was called on tx " + this);
refresh();
// register transaction
implementation.getTxManager().registerTx(this);
@@ -914,11 +905,11 @@
/**
* Is the associated database non-null and open? ODMG 3.0 says it must be.
*/
- if ((curDB == null) || !curDB.isOpen())
+ if((curDB == null) || !curDB.isOpen())
{
throw new DatabaseClosedException("Database is not open. Must have an open DB to begin the Tx.");
}
- if (isOpen())
+ if(isOpen())
{
log.error("Transaction is already open");
throw new org.odmg.TransactionInProgressException("Impossible to call begin on already opened tx");
@@ -937,6 +928,7 @@
/**
* Get object by identity. First lookup among objects registered in the
* transaction, then in persistent storage.
+ *
* @param id The identity
* @return The object
* @throws PersistenceBrokerException
@@ -946,7 +938,7 @@
{
checkOpen();
ObjectEnvelope envelope = objectEnvelopeTable.getByIdentity(id);
- if (envelope != null)
+ if(envelope != null)
{
return (envelope.needsDelete() ? null : envelope.getObject());
}
@@ -968,10 +960,10 @@
ObjectEnvelope envelope = objectEnvelopeTable.getByIdentity(rtObject.getIdentity());
// if we found an envelope, object is already registered --> we do nothing
// than refreshing the object!
- if ((envelope == null))
+ if((envelope == null))
{
// register object itself
- envelope = objectEnvelopeTable.get(rtObject.getIdentity(), rtObject.getObj(), rtObject.isNew());
+ envelope = objectEnvelopeTable.register(rtObject);
}
else
{
@@ -1003,18 +995,16 @@
*/
private void internalLockRegisterReferences(final ClassDescriptor cld, final Object sourceObject, final int lockMode, final boolean cascade) throws LockNotGrantedException
{
- if (implicitLocking)
+ if(implicitLocking)
{
- Iterator i = cld.getObjectReferenceDescriptors(true).iterator();
- ProxyFactory proxyFactory = getBrokerInternal().getProxyFactory();
- 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)
+ if(refObj != null)
{
- boolean isProxy = proxyFactory.isProxy(refObj);
- RuntimeObject rt = isProxy ? new RuntimeObject(refObj, this, false) : new RuntimeObject(refObj, this);
+ RuntimeObject rt = new RuntimeObject(refObj, this);
internalLockRegister(rt, lockMode, cascade);
}
}
@@ -1023,22 +1013,22 @@
private void internalLockRegisterCollections(final ClassDescriptor cld, final Object sourceObject, final int lockMode, boolean cascade) throws LockNotGrantedException
{
- if (implicitLocking)
+ if(implicitLocking)
{
- Iterator i = cld.getCollectionDescriptors(true).iterator();
ProxyFactory proxyFactory = getBrokerInternal().getProxyFactory();
- while (i.hasNext())
+ 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)
+ if(col != null)
{
CollectionProxy proxy = proxyFactory.getCollectionProxy(col);
- if (proxy != null)
+ if(proxy != null)
{
- if (!proxy.isLoaded())
+ if(!proxy.isLoaded())
{
- if (log.isDebugEnabled()) log.debug("adding self as listener to collection proxy");
+ if(log.isDebugEnabled()) log.debug("adding self as listener to collection proxy");
proxy.addListener(this);
registeredCollectionProxies.add(proxy);
continue;
@@ -1048,14 +1038,14 @@
Object item = null;
try
{
- while (colIterator.hasNext())
+ while(colIterator.hasNext())
{
item = colIterator.next();
RuntimeObject rt = new RuntimeObject(item, this);
- if (rt.isProxy())
+ if(rt.isProxy())
{
IndirectionHandler handler = proxyFactory.getIndirectionHandler(item);
- if (!handler.alreadyMaterialized())
+ if(!handler.alreadyMaterialized())
{
registerToIndirectionHandler(handler);
continue;
@@ -1070,7 +1060,7 @@
internalLockRegister(rt, lockMode, cascade);
}
}
- catch (LockNotGrantedException e)
+ catch(LockNotGrantedException e)
{
String eol = SystemUtils.LINE_SEPARATOR;
log.error("Lock not granted, while lock collection references[" +
@@ -1087,10 +1077,11 @@
}
/**
- * this callback is invoked before an Object is materialized
- * within an IndirectionHandler.
- * @param handler the invoking handler
- * @param oid the identity of the object to be materialized
+ * this callback is invoked before an Object is materialized
+ * within an IndirectionHandler.
+ *
+ * @param handler the invoking handler
+ * @param oid the identity of the object to be materialized
*/
public void beforeMaterialization(IndirectionHandler handler, Identity oid)
{
@@ -1098,33 +1089,38 @@
}
/**
- * this callback is invoked after an Object is materialized
- * within an IndirectionHandler.
- * this callback allows to defer registration of objects until
- * it's really neccessary.
- * @param handler the invoking handler
- * @param materializedObject the materialized Object
+ * this callback is invoked after an Object is materialized
+ * within an IndirectionHandler.
+ * this callback allows to defer registration of objects until
+ * it's really neccessary.
+ *
+ * @param handler the invoking handler
+ * @param materializedObject the materialized Object
*/
public void afterMaterialization(IndirectionHandler handler, Object materializedObject)
{
try
{
Identity oid = handler.getIdentity();
- if (log.isDebugEnabled())
- log.debug("deferred registration: " + oid);
+ if(log.isDebugEnabled())
+ log.debug("deferred registration: " + oid);
if(!isOpen())
{
log.error("Proxy object materialization outside of a running tx, obj=" + oid);
- try{throw new Exception("Proxy object materialization outside of a running tx, obj=" + oid);}catch(Exception e)
+ try
{
- e.printStackTrace();
+ throw new Exception("Proxy object materialization outside of a running tx, obj=" + oid);
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
}
}
ClassDescriptor cld = getBroker().getClassDescriptor(materializedObject.getClass());
- RuntimeObject rt = new RuntimeObject(getBrokerInternal(), materializedObject, oid, cld, false, false);
+ RuntimeObject rt = new RuntimeObject(getBrokerInternal(), materializedObject, oid, cld, false);
lockAndRegister(rt, Transaction.READ, isImplicitLocking());
}
- catch (Throwable t)
+ catch(Throwable t)
{
log.error("Register materialized object with this tx failed", t);
throw new LockNotGrantedException(t.getMessage());
@@ -1136,7 +1132,7 @@
{
// unregistering manipulates the registeredIndirectionHandlers vector
// we have to loop through this vector to avoid index proplems.
- for (int i = registeredIndirectionHandlers.size() - 1; i >= 0; i--)
+ for(int i = registeredIndirectionHandlers.size() - 1; i >= 0; i--)
{
unregisterFromIndirectionHandler((IndirectionHandler) registeredIndirectionHandlers.get(i));
}
@@ -1144,7 +1140,7 @@
protected synchronized void unRegisterFromAllCollectionProxies()
{
- for (int i = registeredCollectionProxies.size() - 1; i >= 0; i--)
+ for(int i = registeredCollectionProxies.size() - 1; i >= 0; i--)
{
unregisterFromCollectionProxy((CollectionProxy) registeredCollectionProxies.get(i));
}
@@ -1203,7 +1199,7 @@
if(!(lm instanceof LockManagerOdmgImpl) && unmaterializedLocks.size() > 0)
{
//remove locks for objects which haven't been materialized yet
- for (Iterator it = unmaterializedLocks.iterator(); it.hasNext();)
+ for(Iterator it = unmaterializedLocks.iterator(); it.hasNext();)
{
RuntimeObject rt = (RuntimeObject) it.next();
lm.releaseLock(this, rt.getIdentity());
@@ -1225,7 +1221,7 @@
*/
public PersistenceBrokerInternal getBrokerInternal()
{
- if (broker == null)
+ if(broker == null)
{
checkOpen();
try
@@ -1233,9 +1229,10 @@
checkForDB();
broker = curDB.getBroker();
}
- catch (PBFactoryException e)
+ catch(PBFactoryException e)
{
- log.error("Cannot obtain PersistenceBroker from database object", e);
+ log.error("Cannot obtain 'PersistenceBroker' instance from database object: "
+ + curDB, e);
throw new PersistenceBrokerException(e);
}
}
@@ -1279,6 +1276,7 @@
{
return getBroker().getConfiguration().getOjb().getProxyFactory();
}
+
/**
* @see org.apache.ojb.odmg.TransactionExt#setImplicitLocking(boolean)
*/
@@ -1306,23 +1304,26 @@
*/
public void afterLoading(CollectionProxy colProxy)
{
- if (log.isDebugEnabled()) log.debug("loading a proxied collection a collection: " + colProxy);
+ if(log.isDebugEnabled()) log.debug("loading a proxied collection a collection: " + colProxy);
PersistenceBrokerInternal broker = getBrokerInternal();
- for (Iterator iterator = colProxy.iterator(); iterator.hasNext();)
+ for(Iterator iterator = colProxy.iterator(); iterator.hasNext();)
{
Object o = iterator.next();
if(!isOpen())
{
log.error("Collection proxy materialization outside of a running tx, obj=" + o);
- try{throw new Exception("Collection proxy materialization outside of a running tx, obj=" + o);}
+ try
+ {
+ throw new Exception("Collection proxy materialization outside of a running tx, obj=" + o);
+ }
catch(Exception e)
- {e.printStackTrace();}
+ {
+ e.printStackTrace();
+ }
}
else
{
- Identity oid = broker.serviceIdentity().buildIdentity(o);
- ClassDescriptor cld = broker.getClassDescriptor(broker.getProxyFactory().getRealClass(o));
- RuntimeObject rt = new RuntimeObject(broker, o, oid, cld, false, broker.getProxyFactory().isProxy(o));
+ RuntimeObject rt = new RuntimeObject(o, this, false);
lockAndRegister(rt, Transaction.READ, isImplicitLocking());
}
}
@@ -1332,17 +1333,18 @@
protected void performTransactionAwareBeforeCommit()
{
Enumeration en = objectEnvelopeTable.elements();
- while (en.hasMoreElements())
+ while(en.hasMoreElements())
{
((ObjectEnvelope) en.nextElement()).beforeCommit();
}
}
+
protected void performTransactionAwareAfterCommit()
{
Enumeration en = objectEnvelopeTable.elements();
try
{
- while (en.hasMoreElements())
+ while(en.hasMoreElements())
{
((ObjectEnvelope) en.nextElement()).afterCommit();
}
@@ -1353,10 +1355,11 @@
" after commit you can't rollback - exception will be skipped.", e);
}
}
+
protected void performTransactionAwareBeforeRollback()
{
Enumeration en = objectEnvelopeTable.elements();
- while (en.hasMoreElements())
+ while(en.hasMoreElements())
{
try
{
@@ -1365,16 +1368,17 @@
catch(Exception e)
{
log.error("Unexpected error while perform 'TransactionAware#beforeAbort()' listener before rollback of objects" +
- " - exception will be skipped to complete rollback.", e);
+ " - exception will be skipped to complete rollback.", e);
}
}
}
+
protected void performTransactionAwareAfterRollback()
{
Enumeration en = objectEnvelopeTable.elements();
try
{
- while (en.hasMoreElements())
+ while(en.hasMoreElements())
{
((ObjectEnvelope) en.nextElement()).afterAbort();
}
@@ -1387,46 +1391,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.serviceSessionCache().lookup(oid, SessionCache.LEVEL_DEEP) == null
- && !pb.serviceJdbcAccess().doesExist(cld, oid);
+ cld = pb.getClassDescriptor(obj.getClass());
}
+ // if object was found cache, assume it's old
+ // else make costly check against the DB
+ isNew = pb.serviceSessionCache().lookup(oid, SessionCache.LEVEL_DEEP) == null
+ && !pb.serviceJdbcAccess().doesExist(cld, oid);
}
}
return isNew;
@@ -1475,7 +1476,7 @@
{
for(int i = 0; i < extents.size(); i++)
{
- Class extent = (Class) extents.get(i);
+ Class extent = (Class) extents.get(i);
ClassDescriptor tmp = getBroker().getClassDescriptor(extent);
setCascadingDelete(tmp, result);
}
@@ -1493,7 +1494,7 @@
List collectionRefs = cld.getCollectionDescriptors(true);
for(int i = 0; i < collectionRefs.size(); i++)
{
- Object o = collectionRefs.get(i);
+ Object o = collectionRefs.get(i);
runtimeCascadeDeleteMap.put(o, cascade);
}
}
@@ -1528,6 +1529,7 @@
/**
* Return <em>true</em> if the OJB ordering algorithm is enabled.
+ *
* @see #setOrdering(boolean)
*/
public boolean isOrdering()
@@ -1550,6 +1552,16 @@
this.ordering = ordering;
}
+ public boolean isOptimizedTransientObjectDetection()
+ {
+ return optimizedTransientObjectDetection;
+ }
+
+ public void setOptimizedTransientObjectDetection(boolean optimizedTransientObjectDetection)
+ {
+ this.optimizedTransientObjectDetection = optimizedTransientObjectDetection;
+ }
+
protected void finalize() throws Throwable
{
super.finalize();
@@ -1579,6 +1591,7 @@
//============================================================
// inner class
//============================================================
+
/**
* This was thrown when something wrong with the cascading delete setting.
*/
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.