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 2007/05/16 01:17:23 UTC
svn commit: r538377 -
/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java
Author: arminw
Date: Tue May 15 16:17:22 2007
New Revision: 538377
URL: http://svn.apache.org/viewvc?view=rev&rev=538377
Log:
add support for new cascade type, support for PersistenceChecker, optimize source (move m:n stuff), remove 'link' methods handled by BrokerHelper too
Modified:
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java?view=diff&rev=538377&r1=538376&r2=538377
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java Tue May 15 16:17:22 2007
@@ -37,6 +37,7 @@
import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.PersistenceBrokerException;
import org.apache.ojb.broker.PersistenceBrokerInternal;
+import org.apache.ojb.broker.PersistenceChecker;
import org.apache.ojb.broker.TransactionAbortedException;
import org.apache.ojb.broker.TransactionInProgressException;
import org.apache.ojb.broker.TransactionNotInProgressException;
@@ -150,6 +151,9 @@
private LobHelper lobHelper;
private PBKey pbKey;
private CollectionTypes collectionTypes;
+ private PersistenceChecker persistenceChecker;
+ //private ObjectContextManager contextManager;
+ //private Linker linker;
/**
* List of objects being stored now, allows to avoid infinite
@@ -236,6 +240,29 @@
proxyFactory = AbstractProxyFactory.getProxyFactory();
brokerHelper = new BrokerHelper(this);
collectionTypes = new CollectionTypes();
+ Class persistenceCheckerClass = serviceConnectionManager().getConnectionDescriptor().getPersistenceChecker();
+ try
+ {
+ persistenceChecker = (PersistenceChecker) ClassHelper.newInstance(
+ persistenceCheckerClass, PersistenceBrokerInternal.class, this);
+ }
+ catch(Exception e)
+ {
+ throw new PersistenceBrokerException("Can't instantiate PersistenceChecker implementation class "
+ + persistenceCheckerClass, e);
+ }
+// Class contextManagerClass = serviceConnectionManager().getConnectionDescriptor().getObjectContextManager();
+// try
+// {
+// contextManager = (ObjectContextManager) ClassHelper.newInstance(
+// contextManagerClass, PersistenceBrokerInternal.class, this);
+// }
+// catch(Exception e)
+// {
+// throw new PersistenceBrokerException("Can't instantiate ObjectContext implementation class "
+// + contextManagerClass, e);
+// }
+// linker = new Linker(this);
}
public void configure(Configuration pConfig) throws ConfigurationException
@@ -324,6 +351,16 @@
return relationshipPrefetcherFactory;
}
+ public PersistenceChecker getPersistenceChecker()
+ {
+ return persistenceChecker;
+ }
+
+ public MtoNBroker getMtoNBroker()
+ {
+ return mtoNBroker;
+ }
+
public boolean isClosed()
{
return this.isClosed;
@@ -404,6 +441,8 @@
this.sequenceManager = null;
this.sqlGenerator = null;
this.statementManager = null;
+// this.contextManager.close();
+// this.contextManager = null;
}
public PBKey getPBKey()
@@ -634,7 +673,7 @@
// TODO: arminw: this simple check should do the same - verify
if (oid.isTransient())
{
- String msg = "Cannot delete object without valid PK's: " + obj;
+ String msg = "Can't delete transient (already deleted?) object: " + obj;
logger.error(msg);
return;
}
@@ -665,6 +704,16 @@
/**
* This method perform the delete of the specified object
* based on the {@link org.apache.ojb.broker.metadata.ClassDescriptor}.
+ *
+ * @param cld A intern specified {@link ClassDescriptor}, the real class of the object or a
+ * super-class descriptor.
+ * NOTE: Important to set the super-class descriptor when deleting "table-per-subclass"-inheritance objects.
+ * @param obj The object.
+ * @param ignoreReferences With this flag the automatic deletion/unlinking
+ * of references can be suppressed (independent of the used auto-delete setting in metadata),
+ * except {@link org.apache.ojb.broker.metadata.SuperReferenceDescriptor}
+ * these kind of reference (descriptor) will always be performed.
+ * @throws PersistenceBrokerException if some goes wrong - please see the error message for details
*/
private void performDeletion(final ClassDescriptor cld, final Object obj, final Identity oid, final boolean ignoreReferences) throws PersistenceBrokerException
{
@@ -749,7 +798,7 @@
String lastUsedTable = cld.getFullTableName();
if (cld.isExtent())
{
- Iterator extents = getDescriptorRepository().getAllConcreteSubclassDescriptors(cld).iterator();
+ Iterator extents = getDescriptorRepository().getSubclassDescriptors(cld).iterator();
while (extents.hasNext())
{
@@ -783,10 +832,10 @@
* will be deleted if auto-delete is true <b>AND</b>
* the member field containing the object reference is NOT null.
*
- * @param cld The {@link org.apache.ojb.broker.metadata.ClassDescriptor} of the object
- * or of a super class.
- * @param obj Object which we will delete references for
- * @param oid The {@link Identity} of the object.
+ * @param cld A intern specified {@link ClassDescriptor}, the real class of the object or a
+ * super-class descriptor.
+ * NOTE: Important to set the super-class descriptor when deleting "table-per-subclass"-inheritance objects.
+ * @param obj The object.
* @param ignoreReferences With this flag the automatic deletion/unlinking
* of references can be suppressed (independent of the used auto-delete setting in metadata),
* except {@link org.apache.ojb.broker.metadata.SuperReferenceDescriptor}
@@ -797,11 +846,10 @@
{
List listRds = cld.getObjectReferenceDescriptors();
// get all members of obj that are references and delete them
- Iterator i = listRds.iterator();
- while (i.hasNext())
+ for(int i = 0; i < listRds.size(); i++)
{
- ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) i.next();
- if ((!ignoreReferences && rds.getCascadingDelete() == ObjectReferenceDescriptor.CASCADE_OBJECT)
+ ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) listRds.get(i);
+ if ((!ignoreReferences && rds.isCascadingDeleteObject())
|| rds.isSuperReferenceDescriptor())
{
Object referencedObject = rds.getPersistentField().get(obj);
@@ -845,7 +893,7 @@
while (i.hasNext())
{
CollectionDescriptor cds = (CollectionDescriptor) i.next();
- if(cds.getCascadingDelete() != ObjectReferenceDescriptor.CASCADE_NONE)
+ if(!cds.isCascadingDeleteNone())
{
if(cds.isMtoNRelation())
{
@@ -857,7 +905,7 @@
NOTE: User has to take care to populate all referenced objects before delete
the main object to avoid referential constraint violation
*/
- if (cds.getCascadingDelete() == ObjectReferenceDescriptor.CASCADE_OBJECT)
+ if (cds.isCascadingDeleteObject())
{
Object col = cds.getPersistentField().get(obj);
if (col != null)
@@ -874,6 +922,21 @@
}
/**
+ * Store only transient/new objects, if the object is persistent (is already
+ * stored) it's skipped - no update will be performed.
+ */
+ public void storeOnlyNew(Object obj) throws PersistenceBrokerException
+ {
+ Class clazz = getProxyFactory().getRealClass(obj);
+ ClassDescriptor cld = getClassDescriptor(clazz);
+ Identity oid = serviceIdentity().buildIdentity(cld, obj);
+ if(!getPersistenceChecker().isPersistent(obj, cld, oid))
+ {
+ store(obj, oid, cld, true);
+ }
+ }
+
+ /**
* Store an Object.
* @see org.apache.ojb.broker.PersistenceBroker#store(Object)
*/
@@ -885,22 +948,8 @@
ClassDescriptor cld = getClassDescriptor(obj.getClass());
Identity oid = serviceIdentity().buildIdentity(cld, obj);
- /*
- if one of the PK fields was null, we assume the objects
- was new and needs insert
- */
- // boolean insert = serviceBrokerHelper().hasNullPKField(cld, obj);
- // TODO: arminw: this should do the same - verify
- boolean insert = oid.isTransient();
- /*
- if PK values are set, lookup cache or db to see whether object
- needs insert or update
- */
- if (!insert)
- {
- insert = objectCache.lookup(oid) == null
- && !serviceBrokerHelper().doesExist(cld, oid, obj);
- }
+ // Check if object needs insert or update
+ boolean insert = !persistenceChecker.isPersistent(obj, cld, oid);
store(obj, oid, cld, insert);
}
@@ -917,7 +966,7 @@
{
// ProxyObjects only have to be updated if their real
// subjects have been loaded
- result = getProxyFactory().getRealObjectIfMaterialized(obj);
+ result = proxyFactory.getRealObjectIfMaterialized(obj);
// null for unmaterialized Proxy
if (result == null)
{
@@ -1051,7 +1100,7 @@
be performed in any case. The "normal" 1:1 references can be ignored when
flag "ignoreReferences" is set
*/
- if((!ignoreReferences && rds.getCascadingStore() != ObjectReferenceDescriptor.CASCADE_NONE)
+ if((!ignoreReferences && !rds.isCascadingStoreNone())
|| rds.isSuperReferenceDescriptor())
{
storeAndLinkOneToOne(false, obj, cld, rds, insert);
@@ -1066,19 +1115,26 @@
* @param rds {@link ObjectReferenceDescriptor} of the real object
* @param insert flag for insert operation
*/
- private void storeAndLinkOneToOne(boolean onlyLink, Object obj, ClassDescriptor cld,
+ public void storeAndLinkOneToOne(boolean onlyLink, Object obj, ClassDescriptor cld,
ObjectReferenceDescriptor rds, boolean insert)
{
Object ref = rds.getPersistentField().get(obj);
- if (!onlyLink && rds.getCascadingStore() == ObjectReferenceDescriptor.CASCADE_OBJECT)
+ if (!onlyLink && ref != null)
{
- if(rds.isSuperReferenceDescriptor())
+ if(rds.isCascadingStoreObject())
+ {
+ if(rds.isSuperReferenceDescriptor())
+ {
+ ClassDescriptor superCld = rds.getClassDescriptor().getSuperClassDescriptor();
+ Identity oid = serviceIdentity().buildIdentity(superCld, ref);
+ storeToDb(ref, superCld, oid, insert);
+ }
+ store(ref);
+ }
+ else if(rds.isCascadingStoreCreate())
{
- ClassDescriptor superCld = rds.getClassDescriptor().getSuperClassDescriptor();
- Identity oid = serviceIdentity().buildIdentity(superCld, ref);
- storeToDb(ref, superCld, oid, insert);
+ storeOnlyNew(ref);
}
- else store(ref);
}
link(obj, cld, rds, ref, insert);
}
@@ -1105,7 +1161,7 @@
CollectionDescriptor cod = (CollectionDescriptor) i.next();
// if CASCADE_NONE was set, do nothing with referenced objects
- if (cod.getCascadingStore() != ObjectReferenceDescriptor.CASCADE_NONE)
+ if (!cod.isCascadingStoreNone())
{
Object referencedObjects = cod.getPersistentField().get(obj);
if (cod.isMtoNRelation())
@@ -1117,10 +1173,10 @@
storeAndLinkOneToMany(false, obj, cod, referencedObjects, insert);
}
- // BRJ: only when auto-update = object (CASCADE_OBJECT)
- //
- if ((cod.getCascadingStore() == ObjectReferenceDescriptor.CASCADE_OBJECT)
- && (referencedObjects instanceof ManageableCollection))
+ // BRJ: only when auto-update is 'object' (CASCADE_OBJECT)
+ // or with CASCADE_CREATE
+ if ((referencedObjects instanceof ManageableCollection)
+ && (cod.isCascadingStoreObject() || cod.isCascadingStoreCreate()))
{
((ManageableCollection) referencedObjects).afterStore(this);
}
@@ -1163,38 +1219,24 @@
*/
Iterator referencedObjectsIterator;
- if(!onlyLink && cod.getCascadingStore() == ObjectReferenceDescriptor.CASCADE_OBJECT)
+ boolean cascadingStoreCreate = cod.isCascadingStoreCreate();
+ if(!onlyLink && (cascadingStoreCreate || cod.isCascadingStoreObject()))
{
referencedObjectsIterator = BrokerHelper.getCollectionIterator(referencedObjects);
while (referencedObjectsIterator.hasNext())
{
- store(referencedObjectsIterator.next());
+ Object refObj = referencedObjectsIterator.next();
+ if(cascadingStoreCreate)
+ {
+ storeOnlyNew(refObj);
+ }
+ else
+ {
+ store(refObj);
+ }
}
}
-
- Collection existingMtoNKeys;
- if(!insert)
- {
- existingMtoNKeys = mtoNBroker.getMtoNImplementor(cod, obj);
- // we can't reuse iterator
- referencedObjectsIterator = BrokerHelper.getCollectionIterator(referencedObjects);
- // remove all entries in indirection table which not be part of referenced objects
- mtoNBroker.deleteMtoNImplementor(cod, obj, referencedObjectsIterator, existingMtoNKeys);
- }
- else
- {
- existingMtoNKeys = Collections.EMPTY_LIST;
- }
- // we can't reuse iterator
- referencedObjectsIterator = BrokerHelper.getCollectionIterator(referencedObjects);
- while (referencedObjectsIterator.hasNext())
- {
- Object refObj = referencedObjectsIterator.next();
- // Now store indirection record
- // BRJ: this could cause integrity problems because
- // obj may not be stored depending on auto-update
- mtoNBroker.storeMtoNImplementor(cod, obj, refObj, existingMtoNKeys);
- }
+ mtoNBroker.storeMtoN(obj, cod, referencedObjects, insert);
}
}
@@ -1208,7 +1250,7 @@
* @param referencedObjects the referenced objects ({@link ManageableCollection} or Collection or Array) or null
* @param insert flag for insert operation
*/
- private void storeAndLinkOneToMany(boolean linkOnly, Object obj, CollectionDescriptor cod,
+ public void storeAndLinkOneToMany(boolean linkOnly, Object obj, CollectionDescriptor cod,
Object referencedObjects, boolean insert)
{
if(referencedObjects == null)
@@ -1249,10 +1291,17 @@
// get the real object before linking
refObj = getProxyFactory().getRealObject(refObj);
link(refObj, refCld, cod, obj, insert);
- // if enabled cascade store and not only link, store the refObj
- if(!linkOnly && cod.getCascadingStore() == ObjectReferenceDescriptor.CASCADE_OBJECT)
+ // if enabled cascade store or store on insert, store the referenced objects
+ if(!linkOnly)
{
- store(refObj);
+ if(cod.isCascadingStoreCreate())
+ {
+ storeOnlyNew(refObj);
+ }
+ else if(cod.isCascadingStoreObject())
+ {
+ store(refObj);
+ }
}
}
}
@@ -1355,70 +1404,6 @@
}
/**
- * Assign FK value of main object with PK values of the reference object.
- *
- * @param obj real object with reference (proxy) object (or real object with set FK values on insert)
- * @param cld {@link ClassDescriptor} of the real object
- * @param rds An {@link ObjectReferenceDescriptor} of real object.
- * @param insert Show if "linking" is done while insert or update.
- */
- public void linkOneToOne(Object obj, ClassDescriptor cld, ObjectReferenceDescriptor rds, boolean insert)
- {
- storeAndLinkOneToOne(true, obj, cld, rds, true);
- }
-
- /**
- * Assign FK value to all n-side objects referenced by given object.
- *
- * @param obj real object with 1:n reference
- * @param cod {@link CollectionDescriptor} of referenced 1:n objects
- * @param insert flag signal insert operation, false signals update operation
- */
- public void linkOneToMany(Object obj, CollectionDescriptor cod, boolean insert)
- {
- Object referencedObjects = cod.getPersistentField().get(obj);
- storeAndLinkOneToMany(true, obj, cod,referencedObjects, insert);
- }
-
- /**
- * Assign FK values and store entries in indirection table
- * for all objects referenced by given object.
- *
- * @param obj real object with 1:n reference
- * @param cod {@link CollectionDescriptor} of referenced 1:n objects
- * @param insert flag signal insert operation, false signals update operation
- */
- public void linkMtoN(Object obj, CollectionDescriptor cod, boolean insert)
- {
- Object referencedObjects = cod.getPersistentField().get(obj);
- storeAndLinkMtoN(true, obj, cod, referencedObjects, insert);
- }
-
- public void unlinkXtoN(Object obj, CollectionDescriptor col)
- {
- if(col.isMtoNRelation())
- {
- // if this is a m:n mapped table, remove entries from indirection table
- mtoNBroker.deleteMtoNImplementor(col, obj);
- }
- else
- {
- Object collectionObject = col.getPersistentField().get(obj);
- if (collectionObject != null)
- {
- Iterator colIterator = BrokerHelper.getCollectionIterator(collectionObject);
- ClassDescriptor cld = null;
- while (colIterator.hasNext())
- {
- Object target = colIterator.next();
- if(cld == null) cld = getClassDescriptor(getProxyFactory().getRealClass(target));
- unlinkFK(target, cld, col);
- }
- }
- }
- }
-
- /**
* Retrieve all References (also Collection-attributes) of a given instance.
* Loading is forced, even if the collection- and reference-descriptors differ.
* @param pInstance the persistent instance to work with
@@ -1623,7 +1608,7 @@
// we can lookup all tables of the extent classes:
if (newObj == null && cld.isExtent())
{
- Iterator extents = getDescriptorRepository().getAllConcreteSubclassDescriptors(cld).iterator();
+ Iterator extents = getDescriptorRepository().getSubclassDescriptors(cld).iterator();
while (extents.hasNext())
{
@@ -2239,7 +2224,7 @@
iteratorMap.put(cld.getFullTableName() ,wrapWithPagingIteratorIfNeeded(tmp, query));
}
- Iterator extents = getDescriptorRepository().getAllConcreteSubclassDescriptors(cld).iterator();
+ Iterator extents = getDescriptorRepository().getSubclassDescriptors(cld).iterator();
while (extents.hasNext())
{
ClassDescriptor extCld = (ClassDescriptor) extents.next();
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org