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 2005/12/04 03:50:30 UTC
cvs commit: db-ojb/src/java/org/apache/ojb/odmg ObjectEnvelope.java ObjectEnvelopeTable.java RuntimeObject.java TransactionImpl.java
arminw 2005/12/03 18:50:30
Modified: src/java/org/apache/ojb/odmg Tag: OJB_1_0_RELEASE
ObjectEnvelope.java ObjectEnvelopeTable.java
RuntimeObject.java TransactionImpl.java
Log:
fix problem with persistence by reachability, improvements
Revision Changes Path
No revision
No revision
1.32.2.19 +173 -128 db-ojb/src/java/org/apache/ojb/odmg/ObjectEnvelope.java
Index: ObjectEnvelope.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/ObjectEnvelope.java,v
retrieving revision 1.32.2.18
retrieving revision 1.32.2.19
diff -u -r1.32.2.18 -r1.32.2.19
--- ObjectEnvelope.java 6 Sep 2005 11:41:41 -0000 1.32.2.18
+++ ObjectEnvelope.java 4 Dec 2005 02:50:30 -0000 1.32.2.19
@@ -86,7 +86,7 @@
/**
* beforeImage holds a mapping between field
* names and values at the start of the transaction.
- * afterImage holds the mapping at the
+ * currentImage holds the mapping at the
* end of the transaction.
*/
private Map beforeImage;
@@ -96,7 +96,6 @@
private List linkEntryList;
/**
- *
* Create a wrapper by providing an Object.
*/
public ObjectEnvelope(ObjectEnvelopeTable buffer, Identity oid, Object obj, boolean isNewObject)
@@ -106,11 +105,13 @@
this.oid = oid;
// TODO: do we really need to materialize??
myObj = ProxyHelper.getRealObject(obj);
+ prepareInitialState(isNewObject);
/*
- if object is new don't make an image, because we know it needs insert
+ TODO: is it possible to improve this? Take care that "new"
+ objects should support "persistence by reachability" too
+ (detection of new/persistent reference objects after maon object lock)
*/
- if(!isNewObject) refreshObjectImage();
- prepareInitialState(isNewObject);
+ beforeImage = buildObjectImage(getBroker());
}
public PersistenceBrokerInternal getBroker()
@@ -151,14 +152,16 @@
* to allow cleanup of used resources, e.g. remove proxy listener objects
* to avoid invoke of registered objects after tx end.
*/
- public void cleanup(boolean reuse)
+ public void cleanup(boolean reuse, boolean wasInsert)
{
if(currentImage != null)
{
Iterator iterator = currentImage.values().iterator();
while(iterator.hasNext())
{
- EqualsBase base = (EqualsBase) iterator.next();
+ ImageWrapper base = (ImageWrapper) iterator.next();
+ // cleanup image resources, on reuse the ImageWrapper
+ // decide what to do with the resources
if(base != null) base.cleanup(reuse);
}
}
@@ -167,15 +170,22 @@
Iterator iterator = beforeImage.values().iterator();
while(iterator.hasNext())
{
- EqualsBase base = (EqualsBase) iterator.next();
- // we always free resources of the old image
+ ImageWrapper base = (ImageWrapper) iterator.next();
+ // we always free all resources of the old image
if(base != null) base.cleanup(false);
}
}
- if(!reuse) myObj = null;
+ if(reuse)
+ {
+ refreshObjectImage(wasInsert);
+ }
+ else
+ {
+ myObj = null;
+ }
}
- public void refreshObjectImage()
+ private void refreshObjectImage(boolean wasInsert)
{
PersistenceBroker broker = getBroker();
try
@@ -201,6 +211,30 @@
}
currentImage = null;
hasChanged = null;
+ if(wasInsert)
+ {
+ /*
+ on insert we have to replace the PK fields and the version fields, because
+ they populated after the object was written to DB, thus replace all field image values
+ */
+ FieldDescriptor[] flds = getClassDescriptor().getPkFields();
+ for(int i = 0; i < flds.length; i++)
+ {
+ FieldDescriptor fld = flds[i];
+ addFieldImage(beforeImage, fld);
+ }
+ }
+ // TODO: How to handle version fields incremented by the DB?
+ // always refresh the version fields, because these fields will change when written to DB
+ if(getClassDescriptor().isLocking())
+ {
+ FieldDescriptor[] flds = getClassDescriptor().getLockingFields();
+ for(int i = 0; i < flds.length; i++)
+ {
+ FieldDescriptor fld = flds[i];
+ addFieldImage(beforeImage, fld);
+ }
+ }
}
catch(Exception ex)
{
@@ -208,7 +242,7 @@
currentImage = null;
hasChanged = null;
log.error("Can't refresh object image", ex);
- throw new org.odmg.ClassNotPersistenceCapableException(ex.toString());
+ throw new ImageException(ex);
}
}
@@ -306,115 +340,120 @@
*/
private Map buildObjectImage(PersistenceBroker broker) throws PersistenceBrokerException
{
- Map fieldValues = new HashMap();
- ClassDescriptor mif = broker.getClassDescriptor(getObject().getClass());
+ Map imageMap = new HashMap();
+ ClassDescriptor cld = broker.getClassDescriptor(getObject().getClass());
//System.out.println("++++ build image: " + getObject());
+ // register 1:1 references in image
+ buildImageForSingleReferences(imageMap, cld);
+ // put object values to image map
+ buildImageForFields(imageMap, cld);
+ // register 1:n and m:n references in image
+ buildImageForCollectionReferences(imageMap, cld);
+ return imageMap;
+ }
- /**
- * MBAIRD
- * 1. register all 1:1 references
- * field changes to 1:1 mapped objects should also be registered in the map,
- * so that alterations to those related objects will trigger an object to be
- * marked "dirty", otherwise attaching or detaching a 1:1 referenced object will
- * not be updated in ODMG.
- */
- Iterator iter = mif.getObjectReferenceDescriptors(true).iterator();
+ private void buildImageForSingleReferences(Map imageMap, ClassDescriptor cld)
+ {
+ /*
+ register all 1:1 references
+ */
+ Iterator iter = cld.getObjectReferenceDescriptors(true).iterator();
ObjectReferenceDescriptor rds;
while(iter.hasNext())
{
Object referenceObject;
- EqualsRefHelper erh;
+ ReferenceImageWrapper erh;
rds = (ObjectReferenceDescriptor) iter.next();
-
/*
- synchronize on myObj so the ODMG-layer can take a snapshot only of
- fully cached (i.e. with all references + collections) objects
- arminw:
- The PB-api only return full materialized objects, thus it's not
- needed to sync.
- */
-// synchronized(myObj)
-// {
-// referenceObject = rds.getPersistentField().get(myObj);
-// }
- referenceObject = rds.getPersistentField().get(myObj);
-
- /**
- * MBAIRD
- * In the case of a proxy, we check if it has been materialized
- * if it's been materialized, we put it in the map, because it could change.
- * if it hasn't been materialized, it hasn't changed.
- *
- * Also handles virtual proxies.
- *
- * arminw:
- * wrap Object or Identity with a helper class. The main object will get
- * dirty when the 1:1 reference change: add or replaced by another object or deleted
- */
- IndirectionHandler handler = ProxyHelper.getIndirectionHandler(referenceObject);
- // if it is a not materialized proxy, use the Identity
- if(handler != null)
- {
- erh = handler.alreadyMaterialized()
- ? new EqualsRefHelper(handler.getRealSubject())
- : new EqualsRefHelper(handler.getIdentity());
- }
- else
+ arminw:
+ if a "super-reference" is matched (a 1:1 reference used to represent a super class)
+ we don't handle it, because this will be done by the PB-api and could never be change
+ */
+ if(!rds.isSuperReferenceDescriptor())
{
- /*
- arminw:
- if object was serialized and anonymous FK are used in the main object, the FK
- values are null, we have to refresh (re-assign) this values before building field images
- */
- if(referenceObject != null
- && BrokerHelper.hasAnonymousKeyReference(rds.getClassDescriptor(), rds))
+ referenceObject = rds.getPersistentField().get(myObj);
+
+ /**
+ * MBAIRD
+ * In the case of a proxy, we check if it has been materialized
+ * if it's been materialized, we put it in the map, because it could change.
+ * if it hasn't been materialized, it hasn't changed.
+ *
+ * Also handles virtual proxies.
+ *
+ * arminw:
+ * wrap Object or Identity with a helper class. The main object will get
+ * dirty when the 1:1 reference change: add or replaced by another object or deleted
+ */
+ IndirectionHandler handler = ProxyHelper.getIndirectionHandler(referenceObject);
+ // if it is a not materialized proxy, use the Identity
+ if(handler != null)
{
- getBroker().serviceBrokerHelper().link(myObj, rds, false);
+ erh = handler.alreadyMaterialized()
+ ? new ReferenceImageWrapper(handler.getRealSubject())
+ : new ReferenceImageWrapper(handler.getIdentity());
}
- erh = new EqualsRefHelper(referenceObject);
+ else
+ {
+ /*
+ arminw:
+ if object was serialized and anonymous FK are used in the main object, the FK
+ values are null, we have to refresh (re-assign) this values before building field images
+ */
+ if(referenceObject != null
+ && BrokerHelper.hasAnonymousKeyReference(rds.getClassDescriptor(), rds))
+ {
+ getBroker().serviceBrokerHelper().link(myObj, rds, false);
+ }
+ erh = new ReferenceImageWrapper(referenceObject);
+ }
+ /*
+ register the Identity for 1:1 relations only, if change we have
+ to update the main object
+ */
+ imageMap.put(rds, erh);
}
- /*
- register the Identity for 1:1 relations only, if change we have
- to update the main object
- */
- fieldValues.put(rds, erh);
}
+ }
-
- /**
- * MBAIRD
- * 2. register all fields of object (with inherited fields) that aren't collections or references
- */
- FieldDescriptor[] fieldDescs = mif.getFieldDescriptor(true);
+ private void buildImageForFields(Map imageMap, ClassDescriptor cld)
+ {
+ // register all non reference fields of object (with inherited fields)
+ FieldDescriptor[] fieldDescs = cld.getFieldDescriptor(true);
for(int i = 0; i < fieldDescs.length; i++)
{
- FieldDescriptor fld = fieldDescs[i];
- // map 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
- fieldValues.put(fld.getPersistentField().getName(), new EqualsFieldHelper(fld.getJdbcType().getFieldType(), value));
+ addFieldImage(imageMap, fieldDescs[i]);
}
+ }
+ private void addFieldImage(Map imageMap, FieldDescriptor fld)
+ {
+ // map 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
+ imageMap.put(fld.getPersistentField().getName(), new FieldImageWrapper(fld.getJdbcType().getFieldType(), value));
+ }
+ private void buildImageForCollectionReferences(Map imageMap, ClassDescriptor cld)
+ {
/**
* MBAIRD
* 3. now let's register the collection descriptors
*/
- Iterator collections = mif.getCollectionDescriptors(true).iterator();
+ Iterator collections = cld.getCollectionDescriptors(true).iterator();
CollectionDescriptor cds;
while(collections.hasNext())
{
cds = (CollectionDescriptor) collections.next();
Object collectionOrArray = cds.getPersistentField().get(myObj);
- EqualsColHelper ech = new EqualsColHelper(cds, collectionOrArray);
- fieldValues.put(cds, ech);
+ CollectionImageWrapper ech = new CollectionImageWrapper(cds, collectionOrArray);
+ imageMap.put(cds, ech);
}
- return fieldValues;
}
/**
@@ -560,7 +599,7 @@
void markReferenceElements(PersistenceBroker broker)
{
// these cases will be handled by ObjectEnvelopeTable#cascadingDependents()
- if(getModificationState().needsInsert() || getModificationState().needsDelete()) return;
+ // if(getModificationState().needsInsert() || getModificationState().needsDelete()) return;
Map oldImage = getBeforeImage();
Map newImage = getCurrentImage();
@@ -576,8 +615,8 @@
if (entry.getKey() instanceof CollectionDescriptor)
{
CollectionDescriptor cds = (CollectionDescriptor) entry.getKey();
- EqualsColHelper oldEch = (EqualsColHelper) oldImage.get(cds);
- EqualsColHelper newEch = (EqualsColHelper) entry.getValue();
+ CollectionImageWrapper oldEch = (CollectionImageWrapper) oldImage.get(cds);
+ CollectionImageWrapper newEch = (CollectionImageWrapper) entry.getValue();
//System.out.println("");
//System.out.println("mark-oldEch: " + oldEch);
//System.out.println("mark-newEch: " + newEch);
@@ -591,8 +630,8 @@
check for new 1:1 reference object
*/
ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) entry.getKey();
- EqualsRefHelper oldEh = (EqualsRefHelper) oldImage.get(rds);
- EqualsRefHelper newEh = (EqualsRefHelper) newImage.get(rds);
+ ReferenceImageWrapper oldEh = (ReferenceImageWrapper) oldImage.get(rds);
+ ReferenceImageWrapper newEh = (ReferenceImageWrapper) newImage.get(rds);
if(!oldEh.equals(newEh))
{
// the main objects needs link/unlink of the FK to 1:1 reference,
@@ -644,7 +683,7 @@
/**
* Mark object for delete if it's not available in the new Collection.
*/
- private void markDelete(CollectionDescriptor cds, EqualsColHelper oldEch, EqualsColHelper newEch)
+ private void markDelete(CollectionDescriptor cds, CollectionImageWrapper oldEch, CollectionImageWrapper newEch)
{
if (oldEch.references.size() == 0)
{
@@ -656,11 +695,11 @@
{
Map.Entry entry = (Map.Entry) oldIter.next();
Identity oldOid = (Identity) entry.getKey();
- if (!newRefs.containsKey(oldOid) && newEch.status != IS_UNMATERIALIZED_PROXY)
+ if (newEch.status != IS_UNMATERIALIZED_PROXY && !newRefs.containsKey(oldOid))
{
ObjectEnvelope mod = buffer.getByIdentity(oldOid);
// if this object is associated with another object it's
- // not allowed to remove it
+ // not allowed to remove it, thus nothing will change
if(!buffer.isNewAssociatedObject(oldOid))
{
if(mod != null)
@@ -677,7 +716,9 @@
}
else
{
- // when cascade 'true' we remove all dependent objects, so no need to unlink
+ // when cascade 'true' we remove all dependent objects, so no need
+ // to unlink, else we have to unlink all referenced objects of this
+ // object
if(!cascade)
{
mod.setModificationState(mod.getModificationState().markDirty());
@@ -687,7 +728,7 @@
}
else
{
- throw new ImageExcetion("Unexpected behaviour, unregistered object to delete: "
+ throw new ImageException("Unexpected behaviour, unregistered object to delete: "
+ oldOid + ", main object is " + getIdentity());
}
}
@@ -698,7 +739,7 @@
/**
* Mark object for insert if it's not available in the old Collection.
*/
- private void markNew(CollectionDescriptor cds, EqualsColHelper oldEch, EqualsColHelper newEch)
+ private void markNew(CollectionDescriptor cds, CollectionImageWrapper oldEch, CollectionImageWrapper newEch)
{
if (newEch.references.size() == 0)
{
@@ -720,7 +761,12 @@
if ((oldRefs == null) || !oldRefs.containsKey(newOid))
{
ObjectEnvelope mod = buffer.getByIdentity(newOid);
- if(mod == null) mod = buffer.get(newOid, newObj, true);
+ // if the object isn't registered already, it can be 'new' or already 'persistent'
+ if(mod == null)
+ {
+ boolean isNew = getTx().isNewObject(null, newObj, newOid);
+ mod = buffer.get(newOid, newObj, isNew);
+ }
// 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
// the main object
@@ -833,7 +879,7 @@
/**
* Help to compare field values.
*/
- abstract class EqualsBase
+ abstract class ImageWrapper
{
/**
* This method is called before committing the transaction
@@ -849,12 +895,12 @@
/**
* Help to compare field values.
*/
- class EqualsFieldHelper extends EqualsBase
+ final class FieldImageWrapper extends ImageWrapper
{
- FieldType type;
- Object value;
+ final FieldType type;
+ final Object value;
- public EqualsFieldHelper(FieldType type, Object value)
+ public FieldImageWrapper(FieldType type, Object value)
{
this.type = type;
this.value = value;
@@ -873,9 +919,9 @@
}
else
{
- if(valueNew instanceof EqualsFieldHelper)
+ if(valueNew instanceof FieldImageWrapper)
{
- result = type.equals(value, ((EqualsFieldHelper) valueNew).value);
+ result = type.equals(value, ((FieldImageWrapper) valueNew).value);
}
}
// if(!result)
@@ -887,7 +933,7 @@
public String toString()
{
- return "EqualsFieldHelper[type=" + type + "->value=" + value + "]";
+ return "FieldImageWrapper[type=" + type + "->value=" + value + "]";
}
}
@@ -897,17 +943,17 @@
/**
* Help to compare 1:1 references of the main object.
*/
- class EqualsRefHelper extends EqualsBase
+ final class ReferenceImageWrapper extends ImageWrapper
{
Identity oid;
Object value;
- public EqualsRefHelper(Object refObject)
+ public ReferenceImageWrapper(Object refObject)
{
this.value = refObject;
}
- public EqualsRefHelper(Identity oid)
+ public ReferenceImageWrapper(Identity oid)
{
this.oid = oid;
}
@@ -934,9 +980,9 @@
}
else
{
- if(toCompare instanceof EqualsRefHelper)
+ if(toCompare instanceof ReferenceImageWrapper)
{
- EqualsRefHelper other = (EqualsRefHelper) toCompare;
+ ReferenceImageWrapper other = (ReferenceImageWrapper) toCompare;
if(oid == null)
{
if(value != null)
@@ -951,7 +997,6 @@
other.oid = getBroker().serviceIdentity().buildIdentity(other.value);
}
}
- // return oid != null ? oid.equals(other.oid) : other.oid == null;
result = oid != null ? oid.equals(other.oid) : other.oid == null;
}
}
@@ -969,14 +1014,14 @@
/**
* Help to compare 1:n / m:n references of the main object.
*/
- class EqualsColHelper extends EqualsBase implements CollectionProxyListener
+ class CollectionImageWrapper extends ImageWrapper implements CollectionProxyListener
{
- private CollectionDescriptor des;
+ private final CollectionDescriptor des;
private CollectionProxy collectionHandler;
private int status;
- private Map references;
+ private final Map references;
- public EqualsColHelper(CollectionDescriptor des, Object collOrArray)
+ public CollectionImageWrapper(CollectionDescriptor des, Object collOrArray)
{
this.des = des;
references = new HashMap();
@@ -1002,7 +1047,7 @@
*/
public boolean equals(Object obj)
{
- return (obj instanceof EqualsColHelper);
+ return (obj instanceof CollectionImageWrapper);
}
void cleanup(boolean reuse)
@@ -1125,23 +1170,23 @@
* Thrown if something unexpected is happen when handling the
* object images for state detection.
*/
- public static class ImageExcetion extends OJBRuntimeException
+ public static class ImageException extends OJBRuntimeException
{
- public ImageExcetion()
+ public ImageException()
{
}
- public ImageExcetion(String msg)
+ public ImageException(String msg)
{
super(msg);
}
- public ImageExcetion(Throwable cause)
+ public ImageException(Throwable cause)
{
super(cause);
}
- public ImageExcetion(String msg, Throwable cause)
+ public ImageException(String msg, Throwable cause)
{
super(msg, cause);
}
1.32.2.25 +38 -36 db-ojb/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java
Index: ObjectEnvelopeTable.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java,v
retrieving revision 1.32.2.24
retrieving revision 1.32.2.25
diff -u -r1.32.2.24 -r1.32.2.25
--- ObjectEnvelopeTable.java 27 Oct 2005 18:20:20 -0000 1.32.2.24
+++ ObjectEnvelopeTable.java 4 Dec 2005 02:50:30 -0000 1.32.2.25
@@ -244,9 +244,10 @@
while (iter.hasNext())
{
ObjectEnvelope mod = (ObjectEnvelope) mhtObjectEnvelopes.get(iter.next());
+ boolean insert = false;
if(needsCommit)
{
- boolean insert = mod.needsInsert();
+ insert = mod.needsInsert();
mod.getModificationState().commit(mod);
if(reuse && insert)
{
@@ -258,7 +259,7 @@
ObjectEnvelope, because this method will e.g. remove proxy listener
objects for registered objects.
*/
- mod.cleanup(reuse);
+ mod.cleanup(reuse, insert);
}
// add m:n indirection table entries
performM2NLinkEntries();
@@ -274,7 +275,11 @@
while (iter.hasNext())
{
ObjectEnvelope mod = (ObjectEnvelope) mhtObjectEnvelopes.get(iter.next());
- mod.markReferenceElements(broker);
+ // only non transient objects should be performed
+ if(!mod.getModificationState().isTransient())
+ {
+ mod.markReferenceElements(broker);
+ }
}
}
@@ -291,12 +296,15 @@
while (iter.hasNext())
{
ObjectEnvelope mod = (ObjectEnvelope) mhtObjectEnvelopes.get(iter.next());
- if(needsCommit && (mod.getModificationState() != StateOldClean.getInstance()
- || mod.getModificationState() != StateTransient.getInstance()))
+ if(!needsCommit || (mod.getModificationState() == StateOldClean.getInstance()
+ || mod.getModificationState().isTransient()))
+ {
+ // nothing to do
+ }
+ else
{
mod.setModificationState(mod.getModificationState().markClean());
}
- mod.refreshObjectImage();
}
}
}
@@ -310,30 +318,39 @@
{
// using clone to avoid ConcurentModificationException
Iterator iter = ((List) mvOrderOfIds.clone()).iterator();
+ TransactionImpl tx = getTransaction();
ObjectEnvelope mod;
while (iter.hasNext())
{
mod = (ObjectEnvelope) mhtObjectEnvelopes.get(iter.next());
- /*
- now we check if all modified objects has a write lock. On insert of new
- objects we don't need a write lock.
- */
- if(!mod.needsInsert())
+ // ignore transient objects
+ if(!mod.getModificationState().isTransient())
{
- if((mod.needsDelete() || mod.needsUpdate()
- || mod.hasChanged(getTransaction().getBroker())))
+ /*
+ now we check if all modified objects has a write lock. On insert of new
+ objects we don't need a write lock.
+ */
+ if(!mod.needsInsert())
+ {
+ if((mod.needsDelete() || mod.needsUpdate()
+ || mod.hasChanged(tx.getBroker())))
+ {
+ needsCommit = true;
+ // mark object dirty
+ mod.setModificationState(mod.getModificationState().markDirty());
+ ClassDescriptor cld = mod.getClassDescriptor();
+ // if the object isn't already locked, we will do it now
+ if(!mod.isWriteLocked())
+ {
+ tx.doSingleLock(cld, mod.getObject(), mod.getIdentity(), Transaction.WRITE);
+ }
+ }
+ }
+ else
{
needsCommit = true;
- // mark object dirty
- mod.setModificationState(mod.getModificationState().markDirty());
- ClassDescriptor cld = mod.getClassDescriptor();
- if(!mod.isWriteLocked()) getTransaction().doSingleLock(cld, mod.getObject(), mod.getIdentity(), Transaction.WRITE);
}
}
- else
- {
- needsCommit = true;
- }
}
}
@@ -835,19 +852,4 @@
entry.execute(broker);
}
}
-
- /**
- * Set the specified identity to the last position in the order list.
- * Note: The Identity must already exist in order list.
- */
- void moveToLastInOrderList(Identity oid)
- {
- int index = mvOrderOfIds.indexOf(oid);
- // move entry only if exists
- if(index > -1 && index < (mvOrderOfIds.size() - 1))
- {
- Object id = mvOrderOfIds.remove(index);
- mvOrderOfIds.add(id);
- }
- }
}
\ No newline at end of file
1.1.2.5 +2 -28 db-ojb/src/java/org/apache/ojb/odmg/RuntimeObject.java
Index: RuntimeObject.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/RuntimeObject.java,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -u -r1.1.2.4 -r1.1.2.5
--- RuntimeObject.java 3 May 2005 17:09:04 -0000 1.1.2.4
+++ RuntimeObject.java 4 Dec 2005 02:50:30 -0000 1.1.2.5
@@ -106,33 +106,7 @@
void doIsNewObjectCheck(final TransactionImpl tx)
{
- /*
- detection of new 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
- */
- final PersistenceBroker pb = tx.getBroker();
- boolean isNew = pb.serviceBrokerHelper().hasNullPKField(cld, obj);
- if(!isNew)
- {
- // use method call to guaratee creation of oid
- final Identity oid = getIdentity();
- final ObjectEnvelope mod = tx.objectEnvelopeTable.getByIdentity(oid);
- if(mod != 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);
- }
- }
+ boolean isNew = tx.isNewObject(cld, obj, null);
this.isNew = isNew ? Boolean.TRUE : Boolean.FALSE;
}
1.59.2.22 +43 -51 db-ojb/src/java/org/apache/ojb/odmg/TransactionImpl.java
Index: TransactionImpl.java
===================================================================
RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/odmg/TransactionImpl.java,v
retrieving revision 1.59.2.21
retrieving revision 1.59.2.22
diff -u -r1.59.2.21 -r1.59.2.22
--- TransactionImpl.java 27 Oct 2005 18:19:06 -0000 1.59.2.21
+++ TransactionImpl.java 4 Dec 2005 02:50:30 -0000 1.59.2.22
@@ -270,7 +270,7 @@
if(cascade)
{
// if implicite locking is enabled, first add the current object to
- // list of registered objects to avoid
+ // list of registered objects to avoid endless loops on circular objects
registeredObjects.add(rtObject.getIdentity());
// lock and register 1:1 references first
lockAndRegisterReferences(rtObject.getCld(), rtObject.getObj(), lockMode, registeredObjects);
@@ -1331,6 +1331,47 @@
}
/**
+ * Detect new objects.
+ */
+ protected boolean isNewObject(ClassDescriptor cld, Object obj, Identity oid)
+ {
+ /*
+ detection of new 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
+ */
+ final PersistenceBroker pb = getBroker();
+ if(cld == null)
+ {
+ cld = pb.getClassDescriptor(obj.getClass());
+ }
+ boolean isNew = pb.serviceBrokerHelper().hasNullPKField(cld, obj);
+ if(!isNew)
+ {
+ if(oid == null)
+ {
+ oid = pb.serviceIdentity().buildIdentity(cld, obj);
+ }
+ final ObjectEnvelope mod = objectEnvelopeTable.getByIdentity(oid);
+ if(mod != 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);
+ }
+ }
+ return isNew;
+ }
+
+ /**
* Allows to change the <em>cascading delete</em> behavior of the specified reference
* of the target class while this transaction is in use.
*
@@ -1411,27 +1452,6 @@
arminw: Here we use the auto-delete flag defined in metadata
*/
result = ord.getCascadingDelete() == ObjectReferenceDescriptor.CASCADE_OBJECT;
-/*
-arminw:
-these settings are nonsense (my fault), it dosen't make sense to differ cascade delete
-on the used reference type.
-*/
-// if(ord instanceof CollectionDescriptor)
-// {
-// CollectionDescriptor cds = (CollectionDescriptor) ord;
-// if(cds.isMtoNRelation())
-// {
-// result = implementation.cascadingDeleteMtoN;
-// }
-// else
-// {
-// result = implementation.cascadingDeleteOnetoN;
-// }
-// }
-// else
-// {
-// result = implementation.cascadingDeleteOnetoOne;
-// }
}
else
{
@@ -1469,34 +1489,6 @@
this.ordering = ordering;
}
-// /**
-// * @see ImplementationExt#isNoteUserOrder()
-// */
-// public boolean isNoteUserOrder()
-// {
-// return noteUserOrdering;
-// }
-//
-// /**
-// * @see ImplementationExt#setNoteUserOrder(boolean)
-// */
-// public void setNoteUserOrder(boolean noteUserOrder)
-// {
-// this.noteUserOrdering = noteUserOrder;
-// }
-//
-// /**
-// * Move the specified {@link org.apache.ojb.broker.Identity} to the
-// * last position in the order list if {@link #isNoteUserOrder()} returns <em>true</em>.
-// * @param oid The object identity to move.
-// */
-// public void moveToLastInOrderList(Identity oid)
-// {
-// if(isNoteUserOrder())
-// {
-// objectEnvelopeTable.moveToLastInOrderList(oid);
-// }
-// }
//============================================================
// inner class
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org