Return-Path: Mailing-List: contact ojb-dev-help@db.apache.org; run by ezmlm Delivered-To: mailing list ojb-dev@db.apache.org Received: (qmail 44065 invoked by uid 500); 28 Jun 2003 12:46:56 -0000 Received: (qmail 44062 invoked from network); 28 Jun 2003 12:46:56 -0000 Received: from icarus.apache.org (208.185.179.13) by daedalus.apache.org with SMTP; 28 Jun 2003 12:46:56 -0000 Received: (qmail 38483 invoked by uid 1520); 28 Jun 2003 12:46:55 -0000 Date: 28 Jun 2003 12:46:55 -0000 Message-ID: <20030628124655.38482.qmail@icarus.apache.org> From: olegnitz@apache.org To: db-ojb-cvs@apache.org Subject: cvs commit: db-ojb/src/java/org/apache/ojb/otm/swizzle CopySwizzling.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N olegnitz 2003/06/28 05:46:55 Modified: src/java/org/apache/ojb/otm OTMConnection.java OTMKit.java src/java/org/apache/ojb/otm/copy SerializeObjectCopyStrategy.java src/java/org/apache/ojb/otm/core BaseConnection.java ConcreteEditingContext.java Transaction.java src/java/org/apache/ojb/otm/kit SimpleKit.java src/java/org/apache/ojb/otm/swizzle CopySwizzling.java Removed: src/java/org/apache/ojb/otm/cache CacheException.java GlobalCache.java src/java/org/apache/ojb/otm/cache/store HashMapObjectStore.java ObjectStore.java src/java/org/apache/ojb/otm/core RequestContext.java Log: Refactoring to make OTM use the standard PB cache rather than the own one Revision Changes Path 1.6 +4 -0 db-ojb/src/java/org/apache/ojb/otm/OTMConnection.java Index: OTMConnection.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/OTMConnection.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- OTMConnection.java 16 Jun 2003 22:47:26 -0000 1.5 +++ OTMConnection.java 28 Jun 2003 12:46:54 -0000 1.6 @@ -190,4 +190,8 @@ public void invalidate(Identity oid) throws LockingException; + /** + * Close the OTMConnection + */ + public void close(); } 1.6 +5 -6 db-ojb/src/java/org/apache/ojb/otm/OTMKit.java Index: OTMKit.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/OTMKit.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- OTMKit.java 9 Jun 2003 18:55:26 -0000 1.5 +++ OTMKit.java 28 Jun 2003 12:46:54 -0000 1.6 @@ -56,8 +56,6 @@ import org.apache.ojb.broker.Identity; import org.apache.ojb.broker.PBKey; -import org.apache.ojb.otm.cache.GlobalCache; -import org.apache.ojb.otm.cache.store.ObjectStore; import org.apache.ojb.otm.copy.ObjectCopyStrategy; import org.apache.ojb.otm.core.Transaction; import org.apache.ojb.otm.lock.map.LockMap; @@ -103,10 +101,6 @@ public abstract ObjectCopyStrategy getCopyStrategy(Identity oid); - public abstract ObjectStore getCacheStore(); - - public abstract GlobalCache getGlobalCache(); - /** * Should OTM implicitely read lock all objects that are reachable * from the explicitely locked object? The updates to the read locked @@ -114,5 +108,10 @@ * of transaction. **/ public abstract boolean isImplicitLockingUsed(); + + /** + * Should OTM verify each inserted object for presence in the database? + **/ + public abstract boolean isInsertVerified(); } 1.2 +41 -39 db-ojb/src/java/org/apache/ojb/otm/copy/SerializeObjectCopyStrategy.java Index: SerializeObjectCopyStrategy.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/copy/SerializeObjectCopyStrategy.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SerializeObjectCopyStrategy.java 1 Feb 2003 18:39:57 -0000 1.1 +++ SerializeObjectCopyStrategy.java 28 Jun 2003 12:46:54 -0000 1.2 @@ -69,44 +69,46 @@ */ public class SerializeObjectCopyStrategy implements ObjectCopyStrategy { - /** - * This implementation will probably be slower than the metadata - * object copy, but this was easier to implement. - * @see org.apache.ojb.otm.jdo.copy.ObjectCopyStrategy#copy(Object, DescriptorRepository) - */ - public Object copy (Object obj) + /** + * This implementation will probably be slower than the metadata + * object copy, but this was easier to implement. + * @see org.apache.ojb.otm.jdo.copy.ObjectCopyStrategy#copy(Object, DescriptorRepository) + */ + public Object copy (Object obj) throws ObjectCopyException - { - ObjectOutputStream oos = null; - ObjectInputStream ois = null; - try - { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - oos = new ObjectOutputStream(bos); - // serialize and pass the object - oos.writeObject(obj); - oos.flush(); - ByteArrayInputStream bin = - new ByteArrayInputStream(bos.toByteArray()); - ois = new ObjectInputStream(bin); - // return the new object - return ois.readObject(); - } - catch (Exception e) - { - throw new ObjectCopyException(e); - } - finally - { - try - { - oos.close(); - ois.close(); - } - catch (IOException ioe) - { - // ignore - } - } - } + { + ObjectOutputStream oos = null; + ObjectInputStream ois = null; + try + { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + oos = new ObjectOutputStream(bos); + // serialize and pass the object + oos.writeObject(obj); + oos.flush(); + ByteArrayInputStream bin = + new ByteArrayInputStream(bos.toByteArray()); + ois = new ObjectInputStream(bin); + // return the new object + return ois.readObject(); + } + catch (Exception e) + { + throw new ObjectCopyException(e); + } + finally + { + try + { + oos.close(); + if (ois != null) { + ois.close(); + } + } + catch (IOException ioe) + { + // ignore + } + } + } } 1.11 +81 -48 db-ojb/src/java/org/apache/ojb/otm/core/BaseConnection.java Index: BaseConnection.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/core/BaseConnection.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- BaseConnection.java 16 Jun 2003 22:47:26 -0000 1.10 +++ BaseConnection.java 28 Jun 2003 12:46:54 -0000 1.11 @@ -54,18 +54,28 @@ * . */ +//#ifdef JDK13 +import java.lang.reflect.Proxy; +//#else +/* +import com.develop.java.lang.reflect.Proxy; +*/ +//#endif import java.util.Iterator; import org.apache.ojb.broker.Identity; import org.apache.ojb.broker.PBKey; import org.apache.ojb.broker.PersistenceBroker; +import org.apache.ojb.broker.PersistenceBrokerFactory; +import org.apache.ojb.broker.VirtualProxy; +import org.apache.ojb.broker.accesslayer.IndirectionHandler; import org.apache.ojb.broker.accesslayer.OJBIterator; -import org.apache.ojb.broker.cache.ObjectCache; import org.apache.ojb.broker.core.PersistenceBrokerImpl; import org.apache.ojb.broker.core.PersistenceBrokerFactoryFactory; import org.apache.ojb.broker.metadata.ClassDescriptor; import org.apache.ojb.broker.query.Query; import org.apache.ojb.otm.EditingContext; import org.apache.ojb.otm.OTMConnection; +import org.apache.ojb.otm.copy.ObjectCopyStrategy; import org.apache.ojb.otm.lock.LockManager; import org.apache.ojb.otm.lock.LockType; import org.apache.ojb.otm.lock.LockingException; @@ -81,9 +91,8 @@ implements OTMConnection { - private PersistenceBroker _kernel; + private PersistenceBroker _pb; private Transaction _tx; - private RequestContext _requestContext; private ConcreteEditingContext _editingContext; /** @@ -92,13 +101,18 @@ */ public BaseConnection(PBKey pbKey) { - _requestContext = new RequestContext(this); - _kernel = createKernel(pbKey, _requestContext); + _pb = PersistenceBrokerFactory.createPersistenceBroker(pbKey); + } + + public void close() + { + _pb.close(); + _pb = null; } public PersistenceBroker getKernelBroker() { - return _kernel; + return _pb; } public void setTransaction(Transaction transaction) @@ -115,7 +129,7 @@ } else { - _editingContext = new ConcreteEditingContext(transaction, _kernel); + _editingContext = new ConcreteEditingContext(transaction, _pb); } _tx = transaction; } @@ -126,6 +140,25 @@ } + private static boolean isMaterialized(Object object) + { + IndirectionHandler handler; + + if (Proxy.isProxyClass(object.getClass())) + { + handler = (IndirectionHandler) Proxy.getInvocationHandler(object); + } + else if (object instanceof VirtualProxy) + { + handler = VirtualProxy.getIndirectionHandler((VirtualProxy) object); + } + else + { + return true; + } + return handler.alreadyMaterialized(); + } + ////////////////////////////////////// // OTMConnection protocol ////////////////////////////////////// @@ -137,8 +170,21 @@ throws LockingException { Object object; + ObjectCopyStrategy copyStrategy; + + object = _editingContext.lookup(oid); + + if ((object == null) || !isMaterialized(object)) + { + object = _pb.getObjectByIdentity(oid); + + if (lock != LockType.WRITE_LOCK) + { + copyStrategy = _tx.getKit().getCopyStrategy(oid); + object = copyStrategy.copy(object); + } + } - object = _kernel.getObjectByIdentity(oid); _editingContext.insert(oid, object, lock); return object; } @@ -175,7 +221,7 @@ */ public Iterator getIteratorByQuery(Query query, int lock) { - return new LockingIterator(_kernel.getIteratorByQuery(query), lock); + return new OTMIterator(_pb.getIteratorByQuery(query), lock); } @@ -186,7 +232,7 @@ */ public Identity getIdentity(Object object) { - return new Identity(object, _kernel); + return new Identity(object, _pb); } /** @@ -196,7 +242,7 @@ */ public ClassDescriptor getDescriptorFor(Class clazz) { - return _kernel.getClassDescriptor(clazz); + return _pb.getClassDescriptor(clazz); } /** @@ -211,7 +257,7 @@ _editingContext.insert(oid, null, LockType.WRITE_LOCK); // remove from the cache - _tx.getKit().getGlobalCache().evict(oid); + _pb.serviceObjectCache().remove(oid); } @@ -221,7 +267,7 @@ public void lockForWrite(Object object) throws LockingException { - Identity oid = new Identity(object, _kernel); + Identity oid = new Identity(object, _pb); _editingContext.insert(oid, object, LockType.WRITE_LOCK); } @@ -232,7 +278,7 @@ public void makePersistent(Object object) throws LockingException { - Identity oid = new Identity(object, _kernel); + Identity oid = new Identity(object, _pb); _editingContext.insert(oid, object, LockType.READ_LOCK); } @@ -243,7 +289,7 @@ public void deletePersistent(Object object) throws LockingException { - Identity oid = new Identity(object, _kernel); + Identity oid = new Identity(object, _pb); _editingContext.deletePersistent(oid, object); } @@ -294,44 +340,15 @@ /////////////////////////////////////// - // protected operations - /////////////////////////////////////// - - protected PersistenceBroker createKernel(PBKey pbKey, RequestContext requestContext) - { - PersistenceBrokerKernel pb = new PersistenceBrokerKernel(pbKey); - - // Set the RequestContext to be the cache, so it can connect to the EditingContext - pb.setObjectCache(requestContext); - return pb; - } - - - /////////////////////////////////////// // Inner classes /////////////////////////////////////// - private static class PersistenceBrokerKernel - extends PersistenceBrokerImpl - { - - public PersistenceBrokerKernel(PBKey pbKey) - { - super(pbKey, PersistenceBrokerFactoryFactory.instance()); - } - - public void setObjectCache(ObjectCache cache) - { - objectCache = cache; - } - } - - private class LockingIterator implements Iterator + private class OTMIterator implements Iterator { private final Iterator _it; private final int _lock; - LockingIterator(Iterator it, int lock) + OTMIterator(Iterator it, int lock) { _it = it; _lock = lock; @@ -353,11 +370,27 @@ public Object next() { Object object; + Object ctxObject; + Identity oid; + ObjectCopyStrategy copyStrategy; object = _it.next(); - try + oid = getIdentity(object); + + ctxObject = _editingContext.lookup(oid); + if (ctxObject != null) + { + object = ctxObject; + } + else if (_lock != LockType.WRITE_LOCK && isMaterialized(object)) + { + copyStrategy = _tx.getKit().getCopyStrategy(oid); + object = copyStrategy.copy(object); + } + + try { - _editingContext.insert(getIdentity(object), object, _lock); + _editingContext.insert(oid, object, _lock); } catch (LockingException ex) { 1.14 +246 -88 db-ojb/src/java/org/apache/ojb/otm/core/ConcreteEditingContext.java Index: ConcreteEditingContext.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/core/ConcreteEditingContext.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- ConcreteEditingContext.java 16 Jun 2003 22:47:26 -0000 1.13 +++ ConcreteEditingContext.java 28 Jun 2003 12:46:54 -0000 1.14 @@ -61,6 +61,7 @@ import com.develop.java.lang.reflect.Proxy; */ //#endif +import java.io.Serializable; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; @@ -79,6 +80,7 @@ import org.apache.ojb.broker.accesslayer.ConnectionManagerIF; import org.apache.ojb.broker.accesslayer.IndirectionHandler; import org.apache.ojb.broker.accesslayer.MaterializationListener; +import org.apache.ojb.broker.cache.ObjectCache; import org.apache.ojb.broker.metadata.ClassDescriptor; import org.apache.ojb.broker.metadata.CollectionDescriptor; import org.apache.ojb.broker.metadata.FieldDescriptor; @@ -86,8 +88,6 @@ import org.apache.ojb.broker.metadata.fieldaccess.PersistentField; import org.apache.ojb.broker.util.ArrayIterator; import org.apache.ojb.otm.EditingContext; -import org.apache.ojb.otm.OTMKit; -import org.apache.ojb.otm.cache.GlobalCache; import org.apache.ojb.otm.lock.LockManager; import org.apache.ojb.otm.lock.LockType; import org.apache.ojb.otm.lock.LockingException; @@ -109,6 +109,8 @@ private ArrayList _order; private Transaction _tx; private PersistenceBroker _pb; + private HashMap _original; + private HashMap _checkpointed; ////////////////////////////////////////// // Constructor @@ -120,6 +122,8 @@ _pb = pb; _objects = new HashMap(); _order = new ArrayList(); + _original = new HashMap(); + _checkpointed = _original; } ////////////////////////////////////////// @@ -139,7 +143,10 @@ throws LockingException { ContextEntry entry; - OTMKit kit; + LockManager lockManager; + Swizzling swizzlingStrategy; + IndirectionHandler handler = null; + Object cachedObject; if (lock == LockType.NO_LOCK) { @@ -147,58 +154,101 @@ } entry = (ContextEntry) _objects.get(oid); - kit = _tx.getKit(); + lockManager = LockManager.getInstance(); + swizzlingStrategy = _tx.getKit().getSwizzlingStrategy(); + + if (newObj != null) + { + handler = getIndirectionHandler(newObj); + if ((handler != null) && handler.alreadyMaterialized()) + { + newObj = handler.getRealSubject(); + handler = null; + } + } if (entry == null) { - LockManager lockManager = LockManager.getInstance(); lockManager.ensureLock(oid, _tx, lock, _pb); - Swizzling swizzlingStrategy = kit.getSwizzlingStrategy(); Object swizzledObject = swizzlingStrategy.swizzle(newObj, null, _pb); entry = new ContextEntry(swizzledObject); + if (entry.handler != null) + { + entry.handler.addListener(this); + } + else + { + Object origObj; + + if (_tx.getKit().isInsertVerified()) + { + origObj = _pb.getObjectByIdentity(oid); + } + else + { + ObjectCache cache = _pb.serviceObjectCache(); + origObj = cache.lookup(oid); + } + if (origObj == null) + { + entry.state = State.PERSISTENT_NEW; + } + else + { + _original.put(oid, getFields(origObj)); + } + } _objects.put(oid, entry); } else { - LockManager lockManager = LockManager.getInstance(); - Swizzling swizzlingStrategy = kit.getSwizzlingStrategy(); - // A similar or the same object is present in the context Object oldObj = entry.object; - if (swizzlingStrategy.isSameInstance(oldObj, newObj)) + // The object in context is the same object attempted an insert on + // Ensure we have the correct lock level + lockManager.ensureLock(oid, _tx, lock, _pb); + + if (handler == null) { - // The object in context is the same object attempted an insert on - // Ensure we have the correct lock level - lockManager.ensureLock(oid, _tx, lock, _pb); + if (!swizzlingStrategy.isSameInstance(oldObj, newObj)) + { + // the new object contains data to deal with + if (entry.handler != null) + { + // materialize old object even if it is not + // materialized yet, because we need a place + // to copy the data from the new object + oldObj = entry.handler.getRealSubject(); + entry.handler = null; + } + entry.object = swizzlingStrategy.swizzle(newObj, oldObj, _pb); + } } else { - // It is a similar but different object - lockManager.ensureLock(oid, _tx, lock, _pb); - entry.object = swizzlingStrategy.swizzle(newObj, oldObj, _pb); + if (entry.object == null) + { + // inserting proxy in place of invalidated object + entry.object = newObj; + entry.handler = handler; + entry.handler.addListener(this); + } } } if (!_order.contains(oid)) { _order.add(oid); + } - // perform automatic read lock for all reachable objects - // if the inserted object is materialized - if ((newObj != null) && kit.isImplicitLockingUsed()) - { - IndirectionHandler handler = getIndirectionHandler(newObj); - - if (handler == null || handler.alreadyMaterialized()) - { - lockReachableObjects(newObj); - } - else - { - handler.addListener(this); - } - } + // perform automatic read lock for all reachable objects + // if the inserted object is materialized + if ((handler == null) && (newObj != null) + && _tx.getKit().isImplicitLockingUsed()) + { + lockReachableObjects(newObj); } + return entry; } @@ -243,16 +293,30 @@ //noop } - public void afterMaterialization(IndirectionHandler handler, Object materializedObject) + public void afterMaterialization(IndirectionHandler handler, Object object) { + Identity oid = handler.getIdentity(); + ContextEntry entry = (ContextEntry) _objects.get(oid); + + if (entry == null) + { + return; + } + + _original.put(oid, getFields(object)); + + // replace the proxy object with the real one + entry.object = object; + entry.handler.removeListener(this); + entry.handler = null; + // perform automatic read lock for all reachable objects // if the inserted object is materialized if (_tx.getKit().isImplicitLockingUsed()) { - handler.removeListener(this); try { - lockReachableObjects(materializedObject); + lockReachableObjects(object); } catch (LockingException ex) { @@ -269,13 +333,42 @@ /** * - * Commit this context into the persistent store. If AutoStore is set, this would store all - * the write-locked objects into the persistent store. The EditingContext is not usable after - * a commit. + * Commit this context into the persistent store. + * The EditingContext is not usable after a commit. * */ public void commit() throws TransactionAbortedException { + checkpointInternal(); + releaseLocks(); + _objects.clear(); + _order.clear(); + } + + /** + * + * Writes all changes in this context into the persistent store. + * + */ + public void checkpoint() throws TransactionAbortedException + { + checkpointInternal(); + _checkpointed = new HashMap(); + for (Iterator iterator = _order.iterator(); iterator.hasNext();) + { + Identity oid = (Identity) iterator.next(); + ContextEntry entry = (ContextEntry) _objects.get(oid); + _checkpointed.put(oid, getFields(entry.object)); + } + } + + /** + * + * Writes all changes in this context into the persistent store. + * + */ + private void checkpointInternal() throws TransactionAbortedException + { if (_order.size() == 0) { return; @@ -283,12 +376,12 @@ ConnectionManagerIF connMan = _pb.serviceConnectionManager(); boolean saveBatchMode = connMan.isBatchMode(); - OTMKit kit = _tx.getKit(); - Swizzling swizzlingStrategy = kit.getSwizzlingStrategy(); - GlobalCache cache = kit.getGlobalCache(); + Swizzling swizzlingStrategy = _tx.getKit().getSwizzlingStrategy(); LockManager lockManager = LockManager.getInstance(); Identity[] order = (Identity[]) _order.toArray(new Identity[_order.size()]); Identity[] lockOrder = new Identity[order.length]; + ObjectCache cache = _pb.serviceObjectCache(); + boolean isInsertVerified = _tx.getKit().isInsertVerified(); System.arraycopy(order, 0, lockOrder, 0, order.length); // sort objects in the order of oid.hashCode to avoid deadlocks @@ -319,16 +412,15 @@ continue; } - handler = getIndirectionHandler(entry.object); - - if (handler == null || handler.alreadyMaterialized()) + if (entry.handler == null) // materialized { if (!state.needsUpdate() && !state.needsInsert() && !state.needsDelete()) { - Object object = cache.lookup(oid); + Object[] origFields = (Object[]) _checkpointed.get(oid); - if ((object == null) || isModified(entry.object, object)) + if ((origFields == null) + || isModified(origFields, getFields(entry.object))) { entry.state = state.markDirty(); lockManager.ensureLock(oid, _tx, LockType.WRITE_LOCK, _pb); @@ -337,7 +429,7 @@ } else { - handler.removeListener(this); + entry.handler.removeListener(this); } } @@ -347,14 +439,32 @@ { for (int i = 0; i < order.length; i++) { - ContextEntry entry = (ContextEntry) _objects.get(order[i]); + Identity oid = order[i]; + ContextEntry entry = (ContextEntry) _objects.get(oid); State state = entry.state; Object realTarget; - if (state.needsUpdate() || state.needsInsert()) + if (state.needsInsert()) { realTarget = swizzlingStrategy.getRealTarget(entry.object); - _pb.store(realTarget /*, state*/); + if (isInsertVerified) + { + // PB verifies object existence by default + _pb.store(realTarget); + } + else + { + // PB migth already created the object by auto-update + if (cache.lookup(oid) == null) { + _pb.store(realTarget, state); + } + } + + } + else if (state.needsUpdate()) + { + realTarget = swizzlingStrategy.getRealTarget(entry.object); + _pb.store(realTarget, state); } else if (state.needsDelete()) { @@ -364,9 +474,6 @@ entry.state = state.commit(); } connMan.executeBatch(); - releaseLocks(); - _objects.clear(); - _order.clear(); } finally { @@ -388,8 +495,14 @@ { for (Iterator iterator = _order.iterator(); iterator.hasNext();) { - ContextEntry entry = (ContextEntry) _objects.get(iterator.next()); + Identity oid = (Identity) iterator.next(); + ContextEntry entry = (ContextEntry) _objects.get(oid); + Object[] origFields = (Object[]) _original.get(oid); entry.state = entry.state.rollback(); + if (origFields != null) + { + setFields(entry.object, origFields); + } } releaseLocks(); _objects.clear(); @@ -399,7 +512,7 @@ /** * @return IndirectionHandler for the proxy object or null */ - private IndirectionHandler getIndirectionHandler(Object object) + private static IndirectionHandler getIndirectionHandler(Object object) { if (Proxy.isProxyClass(object.getClass())) { @@ -531,52 +644,83 @@ } } - private boolean isModified(Object newObj, Object oldObj) + private boolean isModified(Object[] newFields, Object[] oldFields) { - ClassDescriptor mif = _pb.getClassDescriptor(newObj.getClass()); + if (newFields.length != oldFields.length) + { + return true; + } + for (int i = 0; i < newFields.length; i++) + { + if (!isEqual(newFields[i], oldFields[i])) + { + return true; + } + } + + return false; + } + + private Object[] getFields(Object obj) + { + ClassDescriptor mif = _pb.getClassDescriptor(obj.getClass()); FieldDescriptor[] fieldDescs = mif.getFieldDescriptions(); + Collection refDescsCol = mif.getObjectReferenceDescriptors(); + ObjectReferenceDescriptor[] refDescs = + (ObjectReferenceDescriptor[]) refDescsCol.toArray( + new ObjectReferenceDescriptor[refDescsCol.size()]); + Object[] fields = new Object[1 + fieldDescs.length + refDescs.length]; + + fields[0] = obj.getClass(); // we must notice if the object class changes + for (int i = 0; i < fieldDescs.length; i++) { FieldDescriptor fd = fieldDescs[i]; PersistentField f = fd.getPersistentField(); - if (!isEqual(f.get(newObj), f.get(oldObj))) - { - return true; - } + fields[1 + i] = f.get(obj); } - Iterator iter = mif.getObjectReferenceDescriptors().iterator(); - ObjectReferenceDescriptor rds = null; - while (iter.hasNext()) + for (int i = 0; i < refDescs.length; i++) { - rds = (ObjectReferenceDescriptor) iter.next(); + ObjectReferenceDescriptor rds = refDescs[i]; PersistentField f = rds.getPersistentField(); - Object newRef = f.get(newObj); - Object oldRef = f.get(oldObj); + fields[1 + fieldDescs.length + i] = f.get(obj); + } - if (newRef == null || oldRef == null) - { - if (newRef != oldRef) - { - return true; - } - else - { - continue; - } - } - - Identity newOid = new Identity(newRef, _pb); - Identity oldOid = new Identity(oldRef, _pb); + return fields; + } - if (!newOid.equals(oldOid)) - { - return true; - } + private void setFields(Object obj, Object[] fields) + { + ClassDescriptor mif = _pb.getClassDescriptor(obj.getClass()); + FieldDescriptor[] fieldDescs = mif.getFieldDescriptions(); + Collection refDescsCol = mif.getObjectReferenceDescriptors(); + ObjectReferenceDescriptor[] refDescs = + (ObjectReferenceDescriptor[]) refDescsCol.toArray( + new ObjectReferenceDescriptor[refDescsCol.size()]); + + if (!fields[0].equals(obj.getClass())) + { + System.err.println("Can't restore the object fields " + + "since its class changed during transaction from " + + fields[0] + " to " + obj.getClass()); + return; + } + + for (int i = 0; i < fieldDescs.length; i++) + { + FieldDescriptor fd = fieldDescs[i]; + PersistentField f = fd.getPersistentField(); + f.set(obj, fields[1 + i]); + } + + for (int i = 0; i < refDescs.length; i++) + { + ObjectReferenceDescriptor rds = refDescs[i]; + PersistentField f = rds.getPersistentField(); + f.set(obj, fields[1 + fieldDescs.length + i]); } - - return false; } @@ -589,9 +733,23 @@ Object object; State state = State.PERSISTENT_CLEAN; - ContextEntry(Object object) + /** + * Handler the proxy object, null if the object is real + */ + IndirectionHandler handler; + + ContextEntry(Object theObject) { - this.object = object; + object = theObject; + if (object != null) + { + handler = getIndirectionHandler(object); + if ((handler != null) && handler.alreadyMaterialized()) + { + object = handler.getRealSubject(); + handler = null; + } + } } } 1.8 +26 -2 db-ojb/src/java/org/apache/ojb/otm/core/Transaction.java Index: Transaction.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/core/Transaction.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- Transaction.java 20 Jun 2003 08:14:05 -0000 1.7 +++ Transaction.java 28 Jun 2003 12:46:54 -0000 1.8 @@ -133,7 +133,7 @@ for (Iterator iterator = _listeners.iterator(); iterator.hasNext();) { TransactionListener listener = (TransactionListener) iterator.next(); - + listener.transactionCommitting(this); } @@ -161,6 +161,30 @@ /** * + * Checkpoint this transaction. + * + */ + public void checkpoint() + throws TransactionException + { + if (!_isInProgress) + { + throw new TransactionNotInProgressException( + "Transaction not in progress, cannot checkpoint"); + } + + for (Iterator iterator = _connections.iterator(); iterator.hasNext();) + { + BaseConnection connection = (BaseConnection) iterator.next(); + ConcreteEditingContext context = + (ConcreteEditingContext) connection.getEditingContext(); + + context.checkpoint(); + } + } + + /** + * * Rollback this transaction. A rollback on the transaction, notifies all its listeners. It, * then initiates a rollback on all associated connections. * @@ -199,7 +223,7 @@ { return _isInProgress; } - + /** * * Associate a connection to this transaction. A OTMConnection can be registered to atmost one 1.9 +31 -22 db-ojb/src/java/org/apache/ojb/otm/kit/SimpleKit.java Index: SimpleKit.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/kit/SimpleKit.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- SimpleKit.java 12 Jun 2003 23:40:51 -0000 1.8 +++ SimpleKit.java 28 Jun 2003 12:46:55 -0000 1.9 @@ -54,12 +54,13 @@ * . */ +import java.io.Serializable; import org.apache.ojb.broker.Identity; import org.apache.ojb.otm.OTMKit; -import org.apache.ojb.otm.cache.GlobalCache; -import org.apache.ojb.otm.cache.store.HashMapObjectStore; -import org.apache.ojb.otm.cache.store.ObjectStore; +import org.apache.ojb.otm.copy.CloneableObjectCopyStrategy; +import org.apache.ojb.otm.copy.NoOpObjectCopyStrategy; import org.apache.ojb.otm.copy.ObjectCopyStrategy; +import org.apache.ojb.otm.copy.OjbCloneable; import org.apache.ojb.otm.copy.SerializeObjectCopyStrategy; import org.apache.ojb.otm.lock.map.InMemoryLockMap; import org.apache.ojb.otm.lock.map.LockMap; @@ -86,9 +87,9 @@ protected Swizzling _swizzlingStrategy; protected LockWaitStrategy _lockWaitStrategy; protected LockMap _lockMap; - protected ObjectCopyStrategy _copyStrategy; - protected ObjectStore _cacheStore; - protected GlobalCache _globalCache; + protected ObjectCopyStrategy _noOpCopyStrategy; + protected ObjectCopyStrategy _serializableCopyStrategy; + protected ObjectCopyStrategy _cloneableCopyStrategy; /** * Constructor for SimpleKit. @@ -100,9 +101,9 @@ _swizzlingStrategy = new CopySwizzling(); _lockWaitStrategy = new TimeoutStrategy(); _lockMap = new InMemoryLockMap(); - _copyStrategy = new SerializeObjectCopyStrategy(); - _cacheStore = new HashMapObjectStore(); - _globalCache = new GlobalCache(this); + _noOpCopyStrategy = new NoOpObjectCopyStrategy(); + _serializableCopyStrategy = new SerializeObjectCopyStrategy(); + _cloneableCopyStrategy = new CloneableObjectCopyStrategy(); } public static SimpleKit getInstance() @@ -156,20 +157,20 @@ */ public ObjectCopyStrategy getCopyStrategy(Identity oid) { - return _copyStrategy; - } + Class clazz = oid.getClass(); - /** - * @see org.apache.ojb.otm.OTMKit#getCacheStore() - */ - public ObjectStore getCacheStore() - { - return _cacheStore; - } - - public GlobalCache getGlobalCache() - { - return _globalCache; + if (OjbCloneable.class.isAssignableFrom(clazz)) + { + return _cloneableCopyStrategy; + } + else if (Serializable.class.isAssignableFrom(clazz)) + { + return _serializableCopyStrategy; + } + else + { + return _noOpCopyStrategy; + } } /** @@ -183,4 +184,12 @@ return true; } + + /** + * Should OTM verify each inserted object for presence in the database? + **/ + public boolean isInsertVerified() + { + return false; + } } 1.3 +2 -1 db-ojb/src/java/org/apache/ojb/otm/swizzle/CopySwizzling.java Index: CopySwizzling.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/otm/swizzle/CopySwizzling.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- CopySwizzling.java 16 Jun 2003 22:47:27 -0000 1.2 +++ CopySwizzling.java 28 Jun 2003 12:46:55 -0000 1.3 @@ -32,8 +32,9 @@ if (!newObj.getClass().equals(oldObj.getClass())) { - throw new IllegalStateException("Trying to swizzle objects of different classes: " + System.err.println("Cannot swizzle objects of different classes: " + newObj.getClass() + " and " + oldObj.getClass()); + return newObj; } ClassDescriptor mif = pb.getClassDescriptor(newObj.getClass());