db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject svn commit: r495677 [5/9] - in /db/ojb/trunk: ./ profile/ src/java/org/apache/ojb/broker/ src/java/org/apache/ojb/broker/accesslayer/ src/java/org/apache/ojb/broker/accesslayer/batch/ src/java/org/apache/ojb/broker/accesslayer/sql/ src/java/org/apache/...
Date Fri, 12 Jan 2007 18:19:45 GMT
Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java Fri Jan 12 10:19:39 2007
@@ -33,7 +33,6 @@
 import org.apache.ojb.broker.Identity;
 import org.apache.ojb.broker.IdentityFactory;
 import org.apache.ojb.broker.ManageableCollection;
-import org.apache.ojb.broker.MtoNImplementor;
 import org.apache.ojb.broker.OptimisticLockException;
 import org.apache.ojb.broker.PBKey;
 import org.apache.ojb.broker.PBState;
@@ -43,7 +42,6 @@
 import org.apache.ojb.broker.TransactionInProgressException;
 import org.apache.ojb.broker.TransactionNotInProgressException;
 import org.apache.ojb.broker.TransientObjectException;
-import org.apache.ojb.broker.lob.LobHelper;
 import org.apache.ojb.broker.accesslayer.ChainingIterator;
 import org.apache.ojb.broker.accesslayer.CollectionCreationContext;
 import org.apache.ojb.broker.accesslayer.ConnectionManagerIF;
@@ -66,6 +64,7 @@
 import org.apache.ojb.broker.core.proxy.IndirectionHandler;
 import org.apache.ojb.broker.core.proxy.ProxyFactory;
 import org.apache.ojb.broker.core.proxy.VirtualProxy;
+import org.apache.ojb.broker.lob.LobHelper;
 import org.apache.ojb.broker.metadata.BatchDescriptor;
 import org.apache.ojb.broker.metadata.ClassDescriptor;
 import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
@@ -76,7 +75,6 @@
 import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
 import org.apache.ojb.broker.metadata.MetadataException;
 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
-import org.apache.ojb.broker.metadata.SequenceDescriptor;
 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
 import org.apache.ojb.broker.query.Query;
 import org.apache.ojb.broker.query.QueryByCriteria;
@@ -99,11 +97,6 @@
  * and allows to store and retrieve arbitrary objects in/from relational
  * databases accessed by JDBC.
  *
- * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
- * @author <a href="mailto:leandro@ibnetwork.com.br">Leandro Rodrigo Saad Cruz<a>
- * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird<a>
- * @author <a href="mailto:jbraeuchi@gmx.ch">Jakob Braeuchi</a>
- *
  * @version $Id$
  */
 public class PersistenceBrokerImpl extends PersistenceBrokerAbstractImpl implements PBState
@@ -121,7 +114,7 @@
     protected boolean brokerLeakDetection;
     protected PersistenceConfiguration persistenceConfiguration;
     protected BrokerHelper brokerHelper;
-    protected MtoNBroker mtoNBroker;
+    public MtoNBroker mtoNBroker;
     protected QueryReferenceBroker referencesBroker;
     /** The proxy factory */
     private ProxyFactory proxyFactory;
@@ -164,7 +157,6 @@
     private IdentityFactory identityFactory;
     private RelationshipPrefetcherFactory relationshipPrefetcherFactory;
     private LobHelper lobHelper;
-    private PBKey pbKey;
 
     /**
      * List of objects being stored now, allows to avoid infinite
@@ -225,23 +217,10 @@
         subContainer             = container.createChildContainer();
 
         JdbcConnectionDescriptor    jcd         = pc.getJdbcConnectionDescriptor();
-        SequenceDescriptor          seqDesc     = jcd.getSequenceDescriptor();
         BatchDescriptor             batchDesc   = jcd.getBatchDescriptor();
 
         subContainer.setSingletonInstance(this);
 
-        // we check whether the sequence descriptor declares different managers/factories
-        if ((seqDesc != null) && (seqDesc.getSequenceManagerClass() != null))
-        {
-            // if a seqMan was defined in repository, use that
-            Class seqManClass = seqDesc.getSequenceManagerClass();
-
-            subContainer.setImplementationClass(SequenceManager.class, seqManClass);
-            if (logger.isDebugEnabled())
-            {
-                logger.debug("Jdbc-Connection-Descriptor '" + jcd.getJcdAlias() + "' use sequence manager: " + seqManClass);
-            }
-        }
         if (batchDesc != null)
         {
             if (batchDesc.getBatchManager() != null)
@@ -258,6 +237,7 @@
             }
         }
 
+        proxyFactory      = (ProxyFactory)subContainer.getSingletonInstance(ProxyFactory.class);
         brokerHelper = new BrokerHelper(this);
         connectionManager = (ConnectionManagerIF)subContainer.getSingletonInstance(ConnectionManagerIF.class);
         identityFactory   = (IdentityFactory)subContainer.getSingletonInstance(IdentityFactory.class);
@@ -265,13 +245,12 @@
         // we're registering the sql generator instance as a singleton so that any pb instance
         // created in the context of this pc will get the same sql generator instance
         sqlGenerator      = (SqlGenerator)subContainer.getSingletonInstance(SqlGenerator.class);
-        dbAccess     = (JdbcAccess) subContainer.getSingletonInstance(JdbcAccess.class);
         batchManager     = (BatchManager) subContainer.getSingletonInstance(BatchManager.class);
         batchManager.setStrategy((BatchStrategy)subContainer.getInstance(BatchStrategy.class));
+        dbAccess     = (JdbcAccess) subContainer.getSingletonInstance(JdbcAccess.class);
         mtoNBroker        = new MtoNBroker(this);
         referencesBroker  = new QueryReferenceBroker(this);
         sessionCache        = (SessionCache)subContainer.getSingletonInstance(SessionCache.class);
-        proxyFactory      = (ProxyFactory)subContainer.getSingletonInstance(ProxyFactory.class);
         queryFactory      = (QueryFactoryNew)subContainer.getSingletonInstance(QueryFactoryNew.class);
         relationshipPrefetcherFactory = new RelationshipPrefetcherFactory(this);
         lobHelper   = (LobHelper)subContainer.getSingletonInstance(LobHelper.class);
@@ -316,7 +295,7 @@
     {
         if (sequenceManager == null)
         {
-            sequenceManager = (SequenceManager)subContainer.getSingletonInstance(SequenceManager.class);
+            sequenceManager = (SequenceManager) subContainer.getSingletonInstance(SequenceManager.class);
         }
         return sequenceManager;
     }
@@ -326,11 +305,6 @@
         return brokerHelper;
     }
 
-    public ObjectCache serviceObjectCache()
-    {
-        return sessionCache.getCachingStrategy(null).getObjectCache();
-    }
-
     public SessionCache serviceSessionCache()
     {
         return sessionCache;
@@ -573,6 +547,10 @@
     {
         if(isInTransaction())
         {
+            if(logger.isEnabledFor(Logger.INFO))
+            {
+                logger.info("Abort transaction for " + this);
+            }
             fireBrokerEvent(BEFORE_ROLLBACK_EVENT);
             setInTransaction(false);
             refreshRegistrationLists();
@@ -601,6 +579,10 @@
         {
             throw new TransactionInProgressException("PersistenceBroker is already in transaction");
         }
+        if(logger.isEnabledFor(Logger.INFO))
+            {
+                logger.info("Begin transaction for " + this);
+            }
         fireBrokerEvent(BEFORE_BEGIN_EVENT);
         setInTransaction(true);
         this.connectionManager.localBegin();
@@ -622,6 +604,10 @@
         {
             throw new TransactionNotInProgressException("PersistenceBroker is NOT in transaction, can't commit");
         }
+        if(logger.isEnabledFor(Logger.INFO))
+            {
+                logger.info("Commit transaction for " + this);
+            }
         fireBrokerEvent(BEFORE_COMMIT_EVENT);
         setInTransaction(false);
         refreshRegistrationLists();
@@ -655,25 +641,37 @@
      */
     public void delete(Object obj, boolean ignoreReferences) throws PersistenceBrokerException
     {
-        if(isTxCheck() && !isInTransaction())
+        if(obj == null)
         {
-            if(logger.isEnabledFor(Logger.ERROR))
-            {
-                String msg = "No running PB-tx found. Please, only delete objects in context of a PB-transaction" +
-                    " to avoid side-effects - e.g. when rollback of complex objects.";
-                try
-                {
-                    throw new Exception("** Delete object without active PersistenceBroker transaction **");
-                }
-                catch(Exception e)
-                {
-                    logger.error(msg, e);
-                }
-            }
+            logger.warn("Specified object to delete is 'null' --> return immediately");
+            return;
+        }
+        // check for tx
+        doTxCheck();
+        try
+        {
+            ClassDescriptor cld = getClassDescriptor(getProxyFactory().getRealClass(obj));
+            Identity oid = serviceIdentity().buildIdentity(cld, obj);
+            doDelete(obj, oid, cld, ignoreReferences);
+        }
+        finally
+        {
+            markedForDelete.clear();
+        }
+    }
+
+    public void delete(Object obj, Identity oid, ClassDescriptor cld, boolean ignoreReferences)
+            throws PersistenceBrokerException
+    {
+        if(obj == null)
+        {
+            logger.warn("Specified object to delete is 'null' --> return immediately");
+            return;
         }
+        doTxCheck();
         try
         {
-            doDelete(obj, ignoreReferences);
+            doDelete(obj, oid, cld, ignoreReferences);
         }
         finally
         {
@@ -693,59 +691,54 @@
      * do delete given object. Should be used by all intern classes to delete
      * objects.
      */
-    private void doDelete(Object obj, boolean ignoreReferences) throws PersistenceBrokerException
+    private void doDelete(Object obj, Identity oid, ClassDescriptor cld, boolean ignoreReferences)
+            throws PersistenceBrokerException
     {
-        //logger.info("DELETING " + obj);
-        // only delete if object is not null
-        if (obj != null)
+        // replace specified object with the real one
+        obj = getProxyFactory().getRealObject(obj);
+        if(cld == null) cld = getClassDescriptor(obj.getClass());
+        if(oid == null) oid = serviceIdentity().buildIdentity(cld, obj);
+
+        /*
+        MBAIRD
+        1. if we are marked for delete already, avoid recursing on this object
+        arminw:
+        use object identity based list, because using objects we get a
+        better performance. I can't find side-effects in doing so.
+         */
+        if (markedForDelete.contains(obj))
         {
-            // replace specified object with the real one
-            obj = getProxyFactory().getRealObject(obj);
+            return;
+        }
 
-            /*
-            MBAIRD
-            1. if we are marked for delete already, avoid recursing on this object
-            arminw:
-            use object identity based list, because using objects we get a
-            better performance. I can't find side-effects in doing so.
-             */
-            if (markedForDelete.contains(obj))
-            {
-                return;
-            }
+        //BRJ: check for valid pk
+        //if (!serviceBrokerHelper().assertValidPkForDelete(cld, obj))
+        // TODO: arminw: this simple check should do the same - verify
+        if (oid.isTransient())
+        {
+            String msg = "Transient object detected. Cannot delete object without valid PK's: " + obj;
+            logger.error(msg);
+            return;
+        }
 
-            ClassDescriptor cld = getClassDescriptor(obj.getClass());
-            Identity oid = serviceIdentity().buildIdentity(cld, obj);
+        /**
+         * MBAIRD
+         * 2. register object in markedForDelete map.
+         */
+        markedForDelete.add(obj);
 
-            //BRJ: check for valid pk
-            //if (!serviceBrokerHelper().assertValidPkForDelete(cld, obj))
-            // TODO: arminw: this simple check should do the same - verify
-            if (oid.isTransient())
-            {
-                String msg = "Cannot delete object without valid PKs: " + obj;
-                logger.error(msg);
-                return;
-            }
-
-            /**
-             * MBAIRD
-             * 2. register object in markedForDelete map.
-             */
-            markedForDelete.add(obj);
-
-            // Invoke events on PersistenceBrokerAware instances and listeners
-            BEFORE_DELETE_EVENT.setTarget(obj);
-            fireBrokerEvent(BEFORE_DELETE_EVENT);
-            BEFORE_DELETE_EVENT.setTarget(null);
-
-            // now perform deletion
-            performDeletion(cld, obj, oid, ignoreReferences);
-
-            // Invoke events on PersistenceBrokerAware instances and listeners
-            AFTER_DELETE_EVENT.setTarget(obj);
-            fireBrokerEvent(AFTER_DELETE_EVENT);
-            AFTER_DELETE_EVENT.setTarget(null);
-        }
+        // Invoke events on PersistenceBrokerAware instances and listeners
+        BEFORE_DELETE_EVENT.setTarget(obj);
+        fireBrokerEvent(BEFORE_DELETE_EVENT);
+        BEFORE_DELETE_EVENT.setTarget(null);
+
+        // now perform deletion
+        performDeletion(cld, obj, oid, ignoreReferences);
+
+        // Invoke events on PersistenceBrokerAware instances and listeners
+        AFTER_DELETE_EVENT.setTarget(obj);
+        fireBrokerEvent(AFTER_DELETE_EVENT);
+        AFTER_DELETE_EVENT.setTarget(null);
     }
 
     /**
@@ -898,7 +891,7 @@
                     }
                     else
                     {
-                        doDelete(referencedObject, ignoreReferences);
+                        doDelete(referencedObject, null, null, ignoreReferences);
                     }
                 }
             }
@@ -928,7 +921,7 @@
                 if(cds.isMtoNRelation())
                 {
                     // if this is a m:n mapped table, remove entries from indirection table
-                    mtoNBroker.deleteMtoNImplementor(cds, obj);
+                    mtoNBroker.deleteAllIndirectionTableEntries(cds.getIndirectionTableDescriptor(), obj);
                 }
                 /*
                 if cascading delete is on, delete all referenced objects.
@@ -943,7 +936,7 @@
                         Iterator colIterator = BrokerHelper.getCollectionIterator(this, col);
                         while (colIterator.hasNext())
                         {
-                            doDelete(colIterator.next(), false);
+                            doDelete(colIterator.next(), null, null, false);
                         }
                     }
                 }
@@ -1039,22 +1032,9 @@
         }
 
         //************************************************
+        // check for runnin tx
+        doTxCheck();
         // now store it:
-        if(isTxCheck() && !isInTransaction())
-        {
-            if(logger.isEnabledFor(Logger.ERROR))
-            {
-                try
-                {
-                    throw new Exception("** Try to store object without active PersistenceBroker transaction **");
-                }
-                catch(Exception e)
-                {
-                    logger.error("No running tx found, please only store in context of an PB-transaction" +
-                    ", to avoid side-effects - e.g. when rollback of complex objects", e);
-                }
-            }
-        }
         // Invoke events on PersistenceBrokerAware instances and listeners
         if (insert)
         {
@@ -1153,7 +1133,7 @@
      * @param rds {@link ObjectReferenceDescriptor} of the real object
      * @param insert flag for insert operation
      */
-    private void storeAndLinkOneToOne(boolean onlyLink, Object obj, ClassDescriptor cld, ObjectReferenceDescriptor rds, boolean insert)
+    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)
@@ -1241,7 +1221,7 @@
      * @param referencedObjects the referenced objects ({@link ManageableCollection} or Collection or Array) or null
      * @param insert flag for insert operation
      */
-    private void storeAndLinkMtoN(boolean onlyLink, Object obj, CollectionDescriptor cod, Object referencedObjects, boolean insert)
+    void storeAndLinkMtoN(boolean onlyLink, Object obj, CollectionDescriptor cod, Object referencedObjects, boolean insert)
     {
         /*
         - if the collection is a collectionproxy and it's not already loaded
@@ -1279,11 +1259,14 @@
             List existingMtoNKeys;
             if(!insert)
             {
-                existingMtoNKeys = mtoNBroker.getMtoNImplementor(cod, obj);
+                // perform batch to guarantee all indirection table entries
+                serviceBatchManager().executeBatch();
+                existingMtoNKeys = mtoNBroker.getAllIndirectionTableEntries(cod.getIndirectionTableDescriptor(), obj);
                 // we can't reuse iterator
                 referencedObjectsIterator = BrokerHelper.getCollectionIterator(this, referencedObjects);
                 // remove all entries in indirection table which not be part of referenced objects
-                mtoNBroker.deleteMtoNImplementor(cod, obj, referencedObjectsIterator, existingMtoNKeys);
+                mtoNBroker.deleteAllNotMatchedIndirectionTableEntries(
+                        cod.getIndirectionTableDescriptor(), obj, referencedObjectsIterator, existingMtoNKeys);
             }
             else
             {
@@ -1297,7 +1280,8 @@
                 // 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.storeIndirectionTableEntry(
+                        cod.getIndirectionTableDescriptor(), obj, refObj, existingMtoNKeys);
             }
         }
     }
@@ -1312,7 +1296,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, Object referencedObjects, boolean insert)
+    void storeAndLinkOneToMany(boolean linkOnly, Object obj, CollectionDescriptor cod, Object referencedObjects, boolean insert)
     {
         if(referencedObjects == null)
         {
@@ -1503,7 +1487,7 @@
         if(col.isMtoNRelation())
         {
             // if this is a m:n mapped table, remove entries from indirection table
-            mtoNBroker.deleteMtoNImplementor(col, obj);
+            mtoNBroker.deleteAllIndirectionTableEntries(col.getIndirectionTableDescriptor(), obj);
         }
         else
         {
@@ -1629,7 +1613,7 @@
     {
         if (logger.isDebugEnabled())
         {
-        	logger.debug("Manually retrieving all references for object " + serviceIdentity().buildIdentity(obj));
+            logger.debug("Manually retrieving all references for object " + serviceIdentity().buildIdentity(obj));
         }
         ClassDescriptor cld = getClassDescriptor(obj.getClass());
         try
@@ -1669,7 +1653,7 @@
         if(logger.isDebugEnabled())
         {
             logger.debug("Retrieving reference named ["+pAttributeName+"] on ["+
-        	            pInstance.getClass().getName()+"]");
+                        pInstance.getClass().getName()+"]");
         }
         ClassDescriptor cld = getClassDescriptor(pInstance.getClass());
         CollectionDescriptor cod = cld.getCollectionDescriptorByName(pAttributeName);
@@ -2149,7 +2133,7 @@
             return;
         }
         // check for running tx and unmaterialized proxy
-        if(!perpareForUpdate(obj))
+        if(!checkUpdatePossible(obj))
         {
             return;
         }
@@ -2211,7 +2195,7 @@
             return;
         }
         // check for running tx and unmaterialized proxy
-        if(!perpareForUpdate(obj))
+        if(!checkUpdatePossible(obj))
         {
             return;
         }
@@ -2269,39 +2253,24 @@
 
         dbAccess.executeUpdate(cld, fields, realObject);
         Identity oid = serviceIdentity().buildIdentity(cld, realObject);
-        serviceSessionCache().cache(oid, realObject, SessionCache.TYPE_WRITE, SessionCache.LEVEL_DEEP);
+        serviceSessionCache().cache(oid, realObject, SessionCache.TYPE_UPDATE, SessionCache.LEVEL_DEEP);
 
         AFTER_UPDATE_EVENT.setTarget(realObject);
         fireBrokerEvent(AFTER_UPDATE_EVENT);
         AFTER_UPDATE_EVENT.setTarget(null);
     }
 
-    private boolean perpareForUpdate(Object obj)
+    private boolean checkUpdatePossible(Object obj)
     {
+        doTxCheck();
         boolean result = true;
-        if(isTxCheck() && !isInTransaction())
-        {
-            if(logger.isEnabledFor(Logger.ERROR))
-            {
-                String msg = "No running PB-tx found. Please, only update objects in context of a PB-transaction" +
-                    " to avoid side-effects - e.g. when rollback of complex objects.";
-                try
-                {
-                    throw new Exception("** Update object without active PersistenceBroker transaction **");
-                }
-                catch(Exception e)
-                {
-                    logger.error(msg, e);
-                }
-            }
-        }
         obj = getProxyFactory().getRealObjectIfMaterialized(obj);
         if (obj == null)    // null for unmaterialized Proxy
         {
             result = false;
             if(logger.isEnabledFor(Logger.INFO))
             {
-                logger.info("Skip update, because object is a unmaterialized proxy object: "
+                logger.info("Skip update, because object is an unmaterialized proxy object: "
                 + getProxyFactory().getIndirectionHandler(obj).getIdentity());
             }
         }
@@ -2373,7 +2342,7 @@
         {
             // BRJ: fk values may be part of pk, but the are not known during
             // creation of Identity. so we have to get them here
-            pkValues = serviceBrokerHelper().getKeyValues(cld, obj);
+            pkValues = serviceBrokerHelper().extractValueArray(serviceBrokerHelper().getKeyValues(cld, obj, false));
             if (!serviceBrokerHelper().assertValidPksForStore(cld.getPkFields(), pkValues))
             {
                 String append = insert ? " on insert" : " on update" ;
@@ -2381,26 +2350,6 @@
             }
         }
 
-        // get super class cld then store it with the object
-        /*
-        now for multiple table inheritance
-        1. store super classes, topmost parent first
-        2. go down through heirarchy until current class
-        3. todo: store to full extent?
-
-// arminw: TODO: The extend-attribute feature dosn't work, should we remove this stuff?
-        This if-clause will go up the inheritance heirarchy to store all the super classes.
-        The id for the top most super class will be the id for all the subclasses too
-         */
-        if(cld.getSuperClass() != null)
-        {
-
-            ClassDescriptor superCld = getDescriptorRepository().getDescriptorFor(cld.getSuperClass());
-            storeToDb(obj, superCld, oid, insert);
-            // arminw: why this?? I comment out this section
-            // storeCollections(obj, cld.getCollectionDescriptors(), insert);
-        }
-
         // 2. store primitive typed attributes (Or is THIS step 3 ?)
         // if obj not present in db use INSERT
         if (insert)
@@ -2412,6 +2361,8 @@
             PK values of the object can be changed by the database (use of database identity columns)
             */
             oid = serviceIdentity().buildIdentity(cld, obj);
+            // Add the object to the cache.
+            serviceSessionCache().cache(oid, obj, SessionCache.TYPE_INSERT, SessionCache.LEVEL_DEEP);
         }
         // else use UPDATE
         else
@@ -2426,10 +2377,9 @@
                 serviceSessionCache().evict(oid, SessionCache.LEVEL_DEEP);
                 throw e;
             }
+            // Add the object to the cache.
+            serviceSessionCache().cache(oid, obj, SessionCache.TYPE_UPDATE, SessionCache.LEVEL_DEEP);
         }
-        // cache object for symmetry with getObjectByXXX()
-        // Add the object to the cache.
-        serviceSessionCache().cache(oid, obj, SessionCache.TYPE_WRITE, SessionCache.LEVEL_DEEP);
         // 3. store 1:n and m:n associations except if we have to skip
         if(!ignoreReferences) storeCollections(obj, cld, insert);
     }
@@ -2691,21 +2641,21 @@
         mtoNBroker.reset();
     }
 
-    /**
-     * @see org.apache.ojb.broker.PersistenceBroker#deleteMtoNImplementor
-     */
-    public void deleteMtoNImplementor(MtoNImplementor m2nImpl) throws PersistenceBrokerException
-    {
-        mtoNBroker.deleteMtoNImplementor(m2nImpl);
-    }
-
-    /**
-     * @see org.apache.ojb.broker.PersistenceBroker#addMtoNImplementor
-     */
-    public void addMtoNImplementor(MtoNImplementor m2n) throws PersistenceBrokerException
-    {
-		mtoNBroker.storeMtoNImplementor(m2n);
-    }
+//    /**
+//     * @see org.apache.ojb.broker.PersistenceBroker#deleteMtoNImplementor
+//     */
+//    public void deleteMtoNImplementor(MtoNImplementor m2nImpl) throws PersistenceBrokerException
+//    {
+//        mtoNBroker.deleteMtoNImplementor(m2nImpl);
+//    }
+//
+//    /**
+//     * @see org.apache.ojb.broker.PersistenceBroker#addMtoNImplementor
+//     */
+//    public void addMtoNImplementor(MtoNImplementor m2n) throws PersistenceBrokerException
+//    {
+//		mtoNBroker.storeMtoNImplementor(m2n);
+//    }
 
     /**
      * Get the Identity out of the Query.
@@ -2739,5 +2689,18 @@
     public QueryFactoryNew getQueryFactory()
     {
         return queryFactory;
+    }
+
+    /**
+     * Check if store/delete operation is allowed.
+     */
+    protected void doTxCheck()
+    {
+        if(isTxCheck() && !isInTransaction())
+        {
+            String msg = "No running PB-tx found. Please, only insert/update/delete objects in context" +
+                    " of a PB-transaction to avoid side-effects - e.g. when rollback of complex objects.";
+            throw new PersistenceBrokerException(msg);
+        }
     }
 }

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java Fri Jan 12 10:19:39 2007
@@ -65,8 +65,7 @@
     private PersistenceBrokerImpl pb;
     private HashMap m_retrievalTasks;
     private ArrayList prefetchingListeners;
-    private final boolean batchRetrieval = true;
-    private final boolean prefetchProxies = true;
+    private boolean prefetchProxies = true;
     private Class classToPrefetch;
     private PBLifeCycleEvent afterLookupEvent;
 
@@ -77,6 +76,24 @@
     }
 
     /**
+     * Return <em>true</em> if proxy object reference pre-fetching is enabled,
+     * <em>false</em> if disabled.
+     */
+    public boolean isPrefetchProxies()
+    {
+        return prefetchProxies;
+    }
+
+    /**
+     * Enable or disable proxy object reference pre-fetching. By default it's enabled.
+     * @param prefetchProxies If set <em>true</em>, reference pre-fetching will be enabled.
+     */
+    public void setPrefetchProxies(boolean prefetchProxies)
+    {
+        this.prefetchProxies = prefetchProxies;
+    }
+
+    /**
      * Retrieves the collection specified by the given context directly, i.e.
      * the laziness of the context is ignored.
      *
@@ -106,7 +123,7 @@
         int fullSize = -1;
         int size = 0;
 
-        final boolean isRetrievalTasksCreated = batchRetrieval && m_retrievalTasks == null;
+        final boolean isRetrievalTasksCreated = m_retrievalTasks == null;
         if (isRetrievalTasksCreated)
         {
             // Maps ReferenceDescriptors to HashSets of owners
@@ -164,8 +181,9 @@
                             && (cld.getProxyPrefetchingLimit() > 0)
                             && addRetrievalTask(candidate, this))
                     {
-                        new PBMaterializationListener(candidate, m_retrievalTasks,
-                                this, cld.getProxyPrefetchingLimit(), pb.getProxyFactory());
+                        if(log.isDebugEnabled()) log.debug("Add proxy prefetch listener for result candidate of query " + query);
+                        new PBMaterializationListener(candidate, m_retrievalTasks, this,
+                        cld.getProxyPrefetchingLimit(), pb.getProxyFactory());
                     }
                 }
             }
@@ -207,6 +225,13 @@
             log.error(e);
             throw e;
         }
+        catch (Exception ex)
+        {
+            // ==> clear materialization cache
+            pb.serviceSessionCache().clearMaterializationCache();
+            log.error(ex);
+            throw new PersistenceBrokerException(ex);
+        }
         finally
         {
             if (iter != null)
@@ -324,23 +349,18 @@
                 Map.Entry entry = (Map.Entry) it.next();
                 Object key = entry.getKey();
 
-                if (!(key instanceof ObjectReferenceDescriptor))
+                if (key instanceof ObjectReferenceDescriptor)
                 {
-                    continue;
-                }
+                    ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) key;
+                    ArrayList owners = (ArrayList) entry.getValue();
 
-                ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) key;
-//                if (ord.isSuperReferenceDescriptor() || ord.isLazy() || (ord.getItemProxyClass() != null))
-                if (ord.isLazy() || (ord.getItemProxyClass() != null))
-                {
-                    continue;
+                    if(!ord.isLazy() && (ord.getItemProxyClass() == null))
+                    {
+                        RelationshipPrefetcher prefetcher = pb.getRelationshipPrefetcherFactory().createRelationshipPrefetcher(ord);
+                        prefetcher.prefetchRelationship(owners);
+                        it.remove();
+                    }
                 }
-
-                RelationshipPrefetcher prefetcher;
-                ArrayList owners = (ArrayList) entry.getValue();
-                prefetcher = pb.getRelationshipPrefetcherFactory().createRelationshipPrefetcher(ord);
-                prefetcher.prefetchRelationship(owners);
-                it.remove();
             }
         }
     }
@@ -348,26 +368,26 @@
     /**
      * Retrieve a single Reference.
      * This implementation retrieves a referenced object from the data backend
-     * if <b>cascade-retrieve</b> is true or if <b>forced</b> is true.
+     * if <b>cascade-retrieve</b> is true or if <b>forceReference</b> is true.
      *
      * @param obj - object that will have it's field set with a referenced object.
      * @param cld - the ClassDescriptor describring obj
      * @param rds - the ObjectReferenceDescriptor of the reference attribute to be loaded
-     * @param forced - if set to true, the reference is loaded even if the rds differs.
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      */
-    public void retrieveReference(Object obj, ClassDescriptor cld, ObjectReferenceDescriptor rds, boolean forced)
+    public void retrieveReference(Object obj, ClassDescriptor cld, ObjectReferenceDescriptor rds, boolean forceReference)
     {
         PersistentField refField;
         Object refObj = null;
 
-        if (forced || rds.getCascadeRetrieve())
+        if (forceReference || rds.getCascadeRetrieve())
         {
             pb.serviceSessionCache().enableMaterializationCache();
             try
             {
                 Identity id = getReferencedObjectIdentity(obj, rds, cld);
                 boolean isRefObjDefined = true;
-
                 if (id == null)
                 {
                     refObj = null;
@@ -378,7 +398,7 @@
                     if (rds.isSuperReferenceDescriptor())
                     {
                         // walk the super-references
-                        ClassDescriptor superCld = cld.getRepository().getDescriptorFor(rds.getItemClass());
+                        ClassDescriptor superCld = cld.getSuperClassDescriptor();
                         retrieveReferences(refObj, superCld, false);
                         retrieveCollections(refObj, superCld, false);
                     }
@@ -386,7 +406,7 @@
                 else if ((m_retrievalTasks != null)
                         && !rds.isLazy()
                         && (rds.getItemProxyClass() == null)
-                        && (pb.getClassDescriptor(rds.getItemClass()).getSelectByFKProcedure() == null))
+                        && (rds.getItemClassDescriptor().getSelectByFKProcedure() == null))
                 {
                     addRetrievalTask(obj, rds);
                     isRefObjDefined = false;
@@ -394,6 +414,7 @@
                 else
                 {
                     refObj = getReferencedObject(id, rds);
+                    if(refObj == null) isRefObjDefined = false;
                 }
 
                 if (isRefObjDefined)
@@ -410,6 +431,7 @@
                         if ((handler != null)
                                 && addRetrievalTask(obj, rds))
                         {
+                            if(log.isDebugEnabled()) log.debug("Add proxy prefetch listener for reference " + rds);
                             new PBMaterializationListener(obj, m_retrievalTasks,
                                     rds, rds.getProxyPrefetchingLimit(), pb.getProxyFactory());
                         }
@@ -430,14 +452,15 @@
     /**
      * Retrieve a single Reference.
      * This implementation retrieves a referenced object from the data backend
-     * if <b>cascade-retrieve</b> is true or if <b>forced</b> is true.
+     * if <b>cascade-retrieve</b> is true or if <b>forceReference</b> is true.
      *
      * @param obj - object that will have it's field set with a referenced object.
      * @param cld - the ClassDescriptor describring obj
      * @param rds - the ObjectReferenceDescriptor of the reference attribute to be loaded
-     * @param forced - if set to true, the reference is loaded even if the rds differs.
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      */
-    public void retrieveProxyReference(Object obj, ClassDescriptor cld, ObjectReferenceDescriptor rds, boolean forced)
+    public void retrieveProxyReference(Object obj, ClassDescriptor cld, ObjectReferenceDescriptor rds, boolean forceReference)
     {
         PersistentField refField;
         Object refObj = null;
@@ -457,9 +480,9 @@
                         && (rds.getProxyPrefetchingLimit() > 0))
                 {
                     IndirectionHandler handler = pb.getProxyFactory().getIndirectionHandler(refObj);
-
                     if ((handler != null) && addRetrievalTask(obj, rds))
                     {
+                        if(log.isDebugEnabled()) log.debug("Add proxy prefetch listener for reference " + rds);
                         new PBMaterializationListener(obj, m_retrievalTasks, rds, rds.getProxyPrefetchingLimit(), pb.getProxyFactory());
                     }
                 }
@@ -478,12 +501,12 @@
      *
      * @param newObj the instance to be loaded or refreshed
      * @param cld the ClassDescriptor of the instance
-     * @param forced if set to true loading is forced even if cld differs.
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      */
-    public void retrieveReferences(Object newObj, ClassDescriptor cld, boolean forced) throws PersistenceBrokerException
+    public void retrieveReferences(Object newObj, ClassDescriptor cld, boolean forceReference) throws PersistenceBrokerException
     {
         Iterator i = cld.getObjectReferenceDescriptors().iterator();
-
         // turn off auto prefetching for related proxies
         final Class saveClassToPrefetch = classToPrefetch;
         classToPrefetch = null;
@@ -494,9 +517,8 @@
             while (i.hasNext())
             {
                 ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) i.next();
-                retrieveReference(newObj, cld, rds, forced);
+                retrieveReference(newObj, cld, rds, forceReference);
             }
-
             pb.serviceSessionCache().disableMaterializationCache();
         }
         catch(RuntimeException e)
@@ -516,12 +538,12 @@
      *
      * @param newObj the instance to be loaded or refreshed
      * @param cld the ClassDescriptor of the instance
-     * @param forced if set to true loading is forced even if cld differs.
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      */
-    public void retrieveProxyReferences(Object newObj, ClassDescriptor cld, boolean forced) throws PersistenceBrokerException
+    public void retrieveProxyReferences(Object newObj, ClassDescriptor cld, boolean forceReference) throws PersistenceBrokerException
     {
         Iterator i = cld.getObjectReferenceDescriptors().iterator();
-
         // turn off auto prefetching for related proxies
         final Class saveClassToPrefetch = classToPrefetch;
         classToPrefetch = null;
@@ -532,7 +554,7 @@
             while (i.hasNext())
             {
                 ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) i.next();
-                retrieveProxyReference(newObj, cld, rds, forced);
+                retrieveProxyReference(newObj, cld, rds, forceReference);
             }
 
             pb.serviceSessionCache().disableMaterializationCache();
@@ -580,7 +602,7 @@
         else
         {
             // ensure that top-level extents are used for Identities
-            return pb.serviceIdentity().buildIdentity(rds.getItemClass(), pb.getTopLevelClass(rds.getItemClass()), fkValues);
+            return pb.serviceIdentity().buildIdentity(rds.getItemClass(), rds.getItemClassDescriptor().getTopLevelClass(), fkValues);
         }
         return null;
     }
@@ -617,14 +639,6 @@
         if (rds.isLazy())
         {
             /*
-            arminw:
-            use real reference class instead of the top-level class,
-            because we want to use a proxy representing the real class
-            not only the top-level class - right?
-            */
-            //referencedProxy = rds.getItemClassDescriptor().getDynamicProxyClass();
-
-            /*
              * andrew.clute:
              * With proxy generation now handled by the ProxyFactory implementations, the class of the Item
              * is now the nessecary parameter to generate a proxy.
@@ -668,43 +682,43 @@
     /**
      * Retrieve a single Collection on behalf of <b>obj</b>.
      * The Collection is retrieved only if <b>cascade.retrieve is true</b>
-     * or if <b>forced</b> is set to true.     *
+     * or if <b>forceReference</b> is set to true.     *
      *
      * @param obj - the object to be updated
      * @param cld - the ClassDescriptor describing obj
      * @param cds - the CollectionDescriptor describing the collection attribute to be loaded
-     * @param forced - if set to true loading is forced, even if cds differs.
+     * @param forceReference - if set to true loading is forced, even if cds differs.
      *
      */
-    public void retrieveCollection(Object obj, ClassDescriptor cld, CollectionDescriptor cds, boolean forced)
+    public void retrieveCollection(Object obj, ClassDescriptor cld, CollectionDescriptor cds, boolean forceReference)
     {
-        doRetrieveCollection(obj, cds, forced);
+        doRetrieveCollection(obj, cds, forceReference, cds.isLazy());
     }
 
     /**
      * Retrieve a single Proxied Collection on behalf of <b>obj</b>.
      * The Collection is retrieved only if <b>cascade.retrieve is true</b>
-     * or if <b>forced</b> is set to true.     *
+     * or if <b>forceReference</b> is set to true.     *
      *
      * @param obj - the object to be updated
      * @param cld - the ClassDescriptor describing obj
      * @param cds - the CollectionDescriptor describing the collection attribute to be loaded
-     * @param forced - if set to true a proxy will be placed, even if cds differs.
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      *
      */
-    public void retrieveProxyCollection(Object obj, ClassDescriptor cld, CollectionDescriptor cds, boolean forced)
+    public void retrieveProxyCollection(Object obj, ClassDescriptor cld, CollectionDescriptor cds, boolean forceReference)
     {
-        doRetrieveCollection(obj, cds, forced);
+        doRetrieveCollection(obj, cds, forceReference, true);
     }
 
-    private void doRetrieveCollection(Object obj, CollectionDescriptor cds, boolean forced)
+    private void doRetrieveCollection(Object obj, CollectionDescriptor cds, boolean forced, boolean lazyLoad)
     {
         if (forced || cds.getCascadeRetrieve())
         {
             if ((m_retrievalTasks != null) && !cds.isLazy()
-                    && !cds.hasProxyItems()
-                    && (cds.getQueryCustomizer() == null)
-                    && (pb.getClassDescriptor(cds.getItemClass()).getSelectByFKProcedure() == null))
+                    && !cds.hasProxyItems() && (cds.getQueryCustomizer() == null)
+                    && (cds.getItemClassDescriptor().getSelectByFKProcedure() == null))
             {
                 addRetrievalTask(obj, cds);
             }
@@ -712,22 +726,22 @@
             {
                 // this collection type will be used:
                 PersistentField collectionField = cds.getPersistentField();
-                Query           fkQuery         = getFKQuery(obj, cds);
-                Object          value;
+                Query fkQuery = getFKQuery(obj, cds);
+                Object value;
 
                 pb.serviceSessionCache().enableMaterializationCache();
                 try
                 {
                     ManageableCollection result = getCollectionByQuery(obj, cds, fkQuery);
-
                     // assign collection to objects attribute
                     // if attribute has an array type build an array, else assign collection directly
                     if (collectionField.getType().isArray() && (result instanceof Collection))
                     {
-                        Collection coll     = (Collection)result;
-                        int        length   = coll.size();
-                        Class      itemtype = collectionField.getType().getComponentType();
-                        int        j        = 0;
+                        // if an array is used we expect a Collection result
+                        Collection coll = (Collection) result;
+                        int length = coll.size();
+                        Class itemtype = collectionField.getType().getComponentType();
+                        int j = 0;
 
                         value = Array.newInstance(itemtype, length);
                         for (Iterator iter = coll.iterator(); iter.hasNext();j++)
@@ -749,6 +763,7 @@
                     {
                         if (addRetrievalTask(obj, cds))
                         {
+                            if(log.isDebugEnabled()) log.debug("Add proxy prefetch listener for collection reference " + cds);
                             new PBCollectionProxyListener(obj,
                                     m_retrievalTasks, cds, cds.getProxyPrefetchingLimit(), pb.getProxyFactory());
                         }
@@ -812,12 +827,12 @@
     }
 
     /**
-     * Get Foreign key query for m:n relationship <br>
+     * Get Foreign key query for m:n relationship
      * supports UNIDIRECTIONAL m:n using QueryByMtoNCriteria.
      *
      * @param obj the owner of the relationship
      * @param cod the CollectionDescriptor
-     * @return org.apache.ojb.broker.query.QueryByCriteria
+     * @return A Query object
      */
     private QueryByCriteria getFKQueryMtoN(Object obj, CollectionDescriptor cod)
     {
@@ -834,7 +849,7 @@
         for (int i = 0; i < itemClassFks.length; i++)
         {
             criteria.addEqualToField(
-                cod.getIndirectionTable() + "." + itemClassFks[i].toString(),
+                cod.getIndirectionTable() + "." + itemClassFks[i],
                 refCld.getPkFields()[i].getAttributeName());
         }
 
@@ -870,12 +885,10 @@
         else
         {
             Criteria criteria = new Criteria();
-
-            for (int idx = 0; idx < fields.length; idx++)
+            for (int i = 0; i < fields.length; i++)
             {
-                criteria.addEqualTo(fields[idx].getAttributeName(), container[idx].getValue());
+                criteria.addEqualTo(fields[i].getAttributeName(), container[i].getValue());
             }
-
             return pb.getQueryFactory().newQuery(refCld.getClassOfObject(), criteria);
         }
     }
@@ -913,12 +926,13 @@
      *
      * @param newObj the instance to be loaded or refreshed
      * @param cld the ClassDescriptor of the instance
-     * @param forced if set to true, loading is forced even if cld differs
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      *
      */
-    public void retrieveCollections(Object newObj, ClassDescriptor cld, boolean forced) throws PersistenceBrokerException
+    public void retrieveCollections(Object newObj, ClassDescriptor cld, boolean forceReference) throws PersistenceBrokerException
     {
-        doRetrieveCollections(newObj, cld, forced, false);
+        doRetrieveCollections(newObj, cld, forceReference, false);
     }
 
     /**
@@ -926,15 +940,16 @@
      *
      * @param newObj the instance to be loaded or refreshed
      * @param cld the ClassDescriptor of the instance
-     * @param forced if set to true, loading is forced even if cld differs
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      *
      */
-    public void retrieveProxyCollections(Object newObj, ClassDescriptor cld, boolean forced) throws PersistenceBrokerException
+    public void retrieveProxyCollections(Object newObj, ClassDescriptor cld, boolean forceReference) throws PersistenceBrokerException
     {
-        doRetrieveCollections(newObj, cld, forced, true);
+        doRetrieveCollections(newObj, cld, forceReference, true);
     }
 
-    private void doRetrieveCollections(Object newObj, ClassDescriptor cld, boolean forced, boolean forceProxyCollection) throws PersistenceBrokerException
+    private void doRetrieveCollections(Object newObj, ClassDescriptor cld, boolean forceReference, boolean forceProxyCollection) throws PersistenceBrokerException
     {
         Iterator i = cld.getCollectionDescriptors().iterator();
 
@@ -950,11 +965,11 @@
                 CollectionDescriptor cds = (CollectionDescriptor) i.next();
                 if(forceProxyCollection)
                 {
-                    retrieveProxyCollection(newObj, cld, cds, forced);
+                    retrieveProxyCollection(newObj, cld, cds, forceReference);
                 }
                 else
                 {
-                    retrieveCollection(newObj, cld, cds, forced);
+                    retrieveCollection(newObj, cld, cds, forceReference);
                 }
             }
             pb.serviceSessionCache().disableMaterializationCache();
@@ -1110,6 +1125,7 @@
             }
             else
             {
+                if(log.isDebugEnabled()) log.debug("Prefetch limit of " + _limit + " entries rearched");
                 toPrefetch = owners.subList(0, _limit);
                 prefetchingAll = false;
             }
@@ -1118,6 +1134,7 @@
             classToPrefetch = prefetcher.getItemClassDescriptor().getClassOfObject();
             try
             {
+                if(log.isDebugEnabled()) log.debug("Start prefetching of objects for " + prefetcher);
                 prefetcher.prefetchRelationship(toPrefetch);
             }
             finally
@@ -1127,10 +1144,12 @@
 
             if (prefetchingAll)
             {
+                if(log.isDebugEnabled()) log.debug("All objects for key " + _key + " prefetched");
                 _retrievalTasks.remove(_key);
             }
             else
             {
+                if(log.isDebugEnabled()) log.debug("Only objects till limit prefetched for key " + _key);
                 // ArrayList documented trick:
                 // "the following idiom removes a range of elements from a list:
                 // list.subList(from, to).clear();

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/ValueContainer.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/ValueContainer.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/ValueContainer.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/ValueContainer.java Fri Jan 12 10:19:39 2007
@@ -18,7 +18,6 @@
 import java.io.Serializable;
 
 import org.apache.commons.lang.ClassUtils;
-import org.apache.commons.lang.builder.EqualsBuilder;
 import org.apache.commons.lang.builder.HashCodeBuilder;
 import org.apache.ojb.broker.metadata.JdbcType;
 
@@ -39,19 +38,22 @@
     private final JdbcType jdbcType;
     private final Object value;
     private final boolean procedureOutParameter;
+    private final boolean procedureInParameter;
     private int hc;
 
-    public ValueContainer(Object value, JdbcType jdbcType)
+    public ValueContainer(final Object value, final JdbcType jdbcType)
     {
         this.jdbcType = jdbcType;
         this.value = value;
         this.procedureOutParameter = false;
+        this.procedureInParameter = false;
     }
 
-    public ValueContainer(Object value, JdbcType jdbcType, boolean procedureOutParameter)
+    public ValueContainer(final Object value, final JdbcType jdbcType, final boolean procedureInParameter, final boolean procedureOutParameter)
     {
         this.value = value;
         this.jdbcType = jdbcType;
+        this.procedureInParameter = procedureInParameter;
         this.procedureOutParameter = procedureOutParameter;
     }
 
@@ -70,6 +72,11 @@
         return procedureOutParameter;
     }
 
+    public boolean isProcedureInParameter()
+    {
+        return procedureInParameter;
+    }
+
     public boolean equals(Object obj)
     {
         if(obj == this) return true;
@@ -80,12 +87,11 @@
             // if jdbcType was null, we can't compare
             result = this.jdbcType != null
                     && this.jdbcType.equals(container.jdbcType)
-                    && this.procedureOutParameter == container.procedureOutParameter;
+                    && this.procedureOutParameter == container.procedureOutParameter
+                    && this.procedureInParameter == container.procedureInParameter;
             if(result)
             {
-                result = new EqualsBuilder()
-                        .append(this.value, container.value)
-                        .isEquals();
+                result = this.value != null ? this.value.equals(container.value) : container.value == null;
             }
         }
         return result;
@@ -93,9 +99,6 @@
 
     public int hashCode()
     {
-//        int hash =  value != null ? value.hashCode() : 0;
-//        hash += jdbcType != null ? jdbcType.hashCode() : 0;
-//        return hash;
         if(hc == 0) hc = new HashCodeBuilder().append(jdbcType).append(value).toHashCode();
         return hc;
     }

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/AbstractIndirectionHandler.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/AbstractIndirectionHandler.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/AbstractIndirectionHandler.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/AbstractIndirectionHandler.java Fri Jan 12 10:19:39 2007
@@ -26,6 +26,7 @@
 import org.apache.ojb.broker.PersistenceBrokerInternal;
 import org.apache.ojb.broker.PersistenceConfiguration;
 import org.apache.ojb.broker.core.PersistenceBrokerThreadMapping;
+import org.apache.ojb.broker.util.logging.Logger;
 import org.apache.ojb.broker.util.logging.LoggerFactory;
 
 /**
@@ -35,17 +36,19 @@
  */
 public abstract class AbstractIndirectionHandler implements IndirectionHandler
 {
-	static final long serialVersionUID = -1993879565033755826L;
+    private static Logger log = LoggerFactory.getLogger(AbstractIndirectionHandler.class);
+
+    static final long serialVersionUID = -1993879565033755826L;
 
     /** The persistence configuration that this indirection handler is bound to */
-	private transient PersistenceConfiguration persistenceConf;
+    private transient PersistenceConfiguration persistenceConf;
     /** The real subject which this is hidden by the proxy */
-    private Object realSubject = null;
+    private Object _realSubject = null;
     /** Represents the identity of the real subject. When the real subject is not
      *  yet materialized, it can be loaded from the underlying db by this identity object */
-    private Identity id = null;
+    private Identity _id = null;
     /** The materialization listeners */
-    private transient ArrayList listeners;
+    private transient ArrayList _listeners;
 
     /**
      * Creates a new indirection handler for the indicated object.
@@ -66,7 +69,7 @@
      */
     public Identity getIdentity()
     {
-        return id;
+        return _id;
     }
 
     /**
@@ -76,11 +79,12 @@
      */
     protected void setIdentity(Identity identity)
     {
-        id = identity;
+        _id = identity;
     }
 
     /**
-     * Returns the key of the persistence broker used by this indirection handler.
+     * Returns the key of the persistence broker used by this indirection
+     * handler.
      * 
      * @return The broker key
      */
@@ -96,14 +100,14 @@
      */
     public synchronized void addListener(MaterializationListener listener)
     {
-        if (listeners == null)
+        if (_listeners == null)
         {
-            listeners = new ArrayList();
+            _listeners = new ArrayList();
         }
         // to avoid multi-add of same listener, do check
-        if(!listeners.contains(listener))
+        if(!_listeners.contains(listener))
         {
-            listeners.add(listener);
+            _listeners.add(listener);
         }
     }
 
@@ -114,9 +118,9 @@
      */
     public synchronized void removeListener(MaterializationListener listener)
     {
-        if (listeners != null)
+        if (_listeners != null)
         {
-            listeners.remove(listener);
+            _listeners.remove(listener);
         }
     }
 
@@ -126,40 +130,40 @@
      */
     protected void beforeMaterialization()
     {
-        if (listeners != null)
+        if (_listeners != null)
         {
             MaterializationListener listener;
 
-            for (int idx = listeners.size() - 1; idx >= 0; idx--)
+            for (int idx = _listeners.size() - 1; idx >= 0; idx--)
             {
-                listener = (MaterializationListener)listeners.get(idx);
-                listener.beforeMaterialization(this, id);
+                listener = (MaterializationListener)_listeners.get(idx);
+                listener.beforeMaterialization(this, _id);
             }
         }
     }
 
     /**
-     * Calls afterMaterialization on all registered listeners in the reverse order
-     * of registration.
+     * Calls afterMaterialization on all registered listeners in the reverse
+     * order of registration.
      */
     protected void afterMaterialization()
     {
-        if (listeners != null)
+        if (_listeners != null)
         {
             MaterializationListener listener;
 
             // listeners may remove themselves during the afterMaterialization callback.
             // thus we must iterate through the listeners vector from back to front
             // to avoid index problems.
-            for (int idx = listeners.size() - 1; idx >= 0; idx--)
+            for (int idx = _listeners.size() - 1; idx >= 0; idx--)
             {
-                listener = (MaterializationListener)listeners.get(idx);
-                listener.afterMaterialization(this, realSubject);
+                listener = (MaterializationListener)_listeners.get(idx);
+                listener.afterMaterialization(this, _realSubject);
             }
         }
     }
 
-	/**
+    /**
      * Gets the persistence broker used by this indirection handler.
      * If no PBKey is available a runtime exception will be thrown.
      * 
@@ -177,7 +181,7 @@
             if no PBKey is set we throw an exception, because we don't
             know which PB (connection) should be used.
             */
-            throw new OJBRuntimeException("Can't find associated PBKey. Need PBKey to obtain a valid" +
+            throw new OJBRuntimeException("Can't find associated PBKey. Need PBKey to obtain a valid " +
                                           "PersistenceBroker instance from intern resources.");
         }
         // first try to use the current threaded broker to avoid blocking
@@ -253,11 +257,11 @@
             // [andrew clute]
             // short-circuit any calls to a finalize methjod if the subject
             // has not been retrieved yet
-            if ("finalize".equals(methodName) && realSubject == null)
+            if ("finalize".equals(methodName) && _realSubject == null)
             {
                 return null;
             }
-            
+
             // [tomdz]
             // Previously the hashcode of the identity would have been used
             // but this requires a compatible hashCode implementation in the
@@ -280,9 +284,9 @@
             // if this is not desired, then the ProxyHandler.toString(Object) method
             // should be used instead (e.g. for logging within OJB)
             /*
-            if ((realSubject == null) && "toString".equals(methodName))
+            if ((_realSubject == null) && "toString".equals(methodName))
             {
-                return "unmaterialized proxy for " + id;
+                return "unmaterialized proxy for " + _id;
             }
             */
 
@@ -293,13 +297,33 @@
                 args[0] = persistenceConf.getOjb().getProxyFactory().getRealObject(args[0]);
             }
 
+            if ("getIndirectionHandler".equals(methodName) && args[0] != null)
+            {
+                return this;
+            }
+
             subject = getRealSubject();
-            return method.invoke(subject, args);
-            // [olegnitz] I've changed the following strange lines
-            // to the above one. Why was this done in such complicated way?
-            // Is it possible that subject doesn't implement the method's interface?
-            // Method m = subject.getClass().getMethod(method.getName(), method.getParameterTypes());
-            // return m.invoke(subject, args);
+            if("toString".equals(methodName) && subject == null)
+            {
+                return null;
+            }
+            /*
+            arminw: If the real subject doesn't exist, return 'null' for all
+            method calls. This could happen e.g. when the FK of a 1:1 reference
+            is the PK of main object. In this case the reference can be null but
+            the FK to the referenced object always exists (because it's the PK of the
+            main object)
+            TODO: Should we log a warn message to indicate abnormal Proxy object behavior?
+            */
+            if(subject == null)
+            {
+                log.warn("Real object of this proxy object doesn't exist, all method will return 'null': " + getIdentity());
+                return null;
+            }
+            else
+            {
+                return method.invoke(subject, args);
+            }
         }
         catch (Exception ex)
         {
@@ -314,13 +338,13 @@
      */
     public Object getRealSubject() throws PersistenceBrokerException
     {
-        if (realSubject == null)
+        if (_realSubject == null)
         {
             beforeMaterialization();
-            realSubject = materializeSubject();
+            _realSubject = materializeSubject();
             afterMaterialization();
         }
-        return realSubject;
+        return _realSubject;
     }
 
     /**
@@ -331,7 +355,7 @@
      */
     public void setRealSubject(Object object)
     {
-        realSubject = object;
+        _realSubject = object;
     }
 
     /**
@@ -345,11 +369,10 @@
         TemporaryBrokerWrapper tmp = getBroker();
         try
         {
-            Object realSubject = tmp.broker.getObjectByIdentity(id);
-
+            Object realSubject = tmp.broker.getObjectByIdentity(_id);
             if (realSubject == null)
             {
-                LoggerFactory.getLogger(IndirectionHandler.class).warn("Can not materialize object for Identity " + id + " - using PBKey " + getBrokerKey());
+                LoggerFactory.getLogger(IndirectionHandler.class).warn("Can not materialize object for Identity " + _id + " - using PBKey " + getBrokerKey());
             }
             return realSubject;
         }
@@ -359,7 +382,7 @@
         }
         finally
         {
-			tmp.close();
+            tmp.close();
         }
     }
 
@@ -370,7 +393,7 @@
      */
     public boolean alreadyMaterialized()
     {
-        return realSubject != null;
+        return _realSubject != null;
     }
 
 

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactory.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactory.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactory.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactory.java Fri Jan 12 10:19:39 2007
@@ -210,4 +210,10 @@
      * @return The string representation
      */
     public String toString(Object proxy);
+
+    /**
+     * Method that returns whether or not this ProxyFactory can generate reference Proxies
+     * for classes regardless if they extend an interface or not.
+     */
+    boolean interfaceRequiredForProxyGeneration();
 }

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactoryCGLIBImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactoryCGLIBImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactoryCGLIBImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactoryCGLIBImpl.java Fri Jan 12 10:19:39 2007
@@ -16,28 +16,28 @@
  */
 
 import java.util.HashMap;
+
 import net.sf.cglib.proxy.Callback;
 import net.sf.cglib.proxy.Enhancer;
 import net.sf.cglib.proxy.Factory;
 
 /**
  * @author andrew.clute
- *
  */
-public class ProxyFactoryCGLIBImpl extends AbstractProxyFactory {
+public class ProxyFactoryCGLIBImpl extends AbstractProxyFactory
+{
 
     private transient HashMap proxyFactories = new HashMap();
-    
-    
+
+
     public Class getDefaultIndirectionHandlerClass()
     {
         return IndirectionHandlerCGLIBImpl.class;
     }
-    
-    
+
+
     /**
      * Returns the class of the base class that the given IndirectionHandler must extend/implement
-     * 
      */
     public Class getIndirectionHandlerBaseClass()
     {
@@ -46,39 +46,46 @@
 
     public OJBProxy createProxy(Class baseClass, IndirectionHandler handler) throws Exception
     {
-        Factory factory = (Factory)proxyFactories.get(baseClass);
-        Object  result  = null;
+        Factory factory = (Factory) proxyFactories.get(baseClass);
+        Object result;
 
-        if (factory == null)
+        if(factory == null)
         {
             Class[] interfaces;
 
-            if (baseClass.isInterface())
+            if(baseClass.isInterface())
             {
-                interfaces = new Class[]{ baseClass, OJBProxy.class };
+                interfaces = new Class[]{baseClass, OJBProxy.class};
             }
             else
             {
-                interfaces = new Class[]{ OJBProxy.class };
+                interfaces = new Class[]{OJBProxy.class};
             }
-            
-            result = (Factory)Enhancer.create(baseClass, interfaces, (Callback)handler);
+
+            result = Enhancer.create(baseClass, interfaces, (Callback) handler);
             proxyFactories.put(baseClass, result);
         }
         else
         {
-            result = factory.newInstance((Callback)handler);
+            result = factory.newInstance((Callback) handler);
         }
-        return (OJBProxy)result;
+        return (OJBProxy) result;
     }
 
-    public boolean isNormalOjbProxy(Object proxyOrObject) {
+    public boolean isNormalOjbProxy(Object proxyOrObject)
+    {
         return super.isNormalOjbProxy(proxyOrObject) && (proxyOrObject instanceof Factory);
     }
 
-    public IndirectionHandler getDynamicIndirectionHandler(Object obj) {
-        return (IndirectionHandler)((Factory)obj).getCallbacks()[0];
+    public IndirectionHandler getDynamicIndirectionHandler(Object obj)
+    {
+        return (IndirectionHandler) ((Factory) obj).getCallbacks()[0];
 
+    }
+
+    public boolean interfaceRequiredForProxyGeneration()
+    {
+        return false;
     }
 
 }

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactoryJDKImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactoryJDKImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactoryJDKImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/core/proxy/ProxyFactoryJDKImpl.java Fri Jan 12 10:19:39 2007
@@ -97,9 +97,6 @@
 
     /**
      * Get interfaces implemented by clazz
-     *
-     * @param clazz
-     * @return
      */
     private Class[] getInterfaces(Class clazz)
     {
@@ -144,6 +141,11 @@
         unique.put(OJBProxy.class.getName(), OJBProxy.class);
 
         return  (Class[])unique.values().toArray(new Class[unique.size()]);
+    }
+
+    public boolean interfaceRequiredForProxyGeneration()
+    {
+        return true;
     }
 
 }

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/locking/IsolationLevels.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/locking/IsolationLevels.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/locking/IsolationLevels.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/locking/IsolationLevels.java Fri Jan 12 10:19:39 2007
@@ -1,11 +1,5 @@
 package org.apache.ojb.broker.locking;
 
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.lang.enums.ValuedEnum;
-
 /* Copyright 2002-2004 The Apache Software Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,6 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.enums.ValuedEnum;
 
 /**
  * This class defines the lock isolation level constants used by

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/locking/LockManagerInMemoryImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/locking/LockManagerInMemoryImpl.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/locking/LockManagerInMemoryImpl.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/locking/LockManagerInMemoryImpl.java Fri Jan 12 10:19:39 2007
@@ -16,13 +16,13 @@
  */
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.collections.list.TreeList;
+import org.apache.commons.collections.map.LinkedMap;
 import org.apache.commons.lang.SystemUtils;
 import org.apache.ojb.broker.util.logging.Logger;
 import org.apache.ojb.broker.util.logging.LoggerFactory;
@@ -45,7 +45,7 @@
      * while still maintaining an O(1) lookup like a normal hashmap. We can then
      * use this to get the oldest entries very quickly, makes cleanup a breeze.
      */
-    private final Map resourceLockMap = new LinkedHashMap(70);
+    private final Map resourceLockMap = new LinkedMap(70);
     private final Map keyLockMap = new HashMap();
     private final LockIsolationManager lockStrategyManager = new LockIsolationManager();
     private long m_lastCleanupAt = System.currentTimeMillis();
@@ -274,13 +274,17 @@
         return false;
     }
 
-    /** The number of locked objects. */
+    /**
+     * The number of locked objects.
+     */
     public int lockedObjects()
     {
         return resourceLockMap.size();
     }
 
-    /** Internal method to detect and remove timed out locks. */
+    /**
+     * Internal method to detect and remove timed out locks.
+     */
     private void checkTimedOutLocks()
     {
         if(System.currentTimeMillis() - m_lastCleanupAt > cleanupFrequency)
@@ -290,7 +294,9 @@
         }
     }
 
-    /** removes all timed out lock entries from the persistent storage. */
+    /**
+     * removes all timed out lock entries from the persistent storage.
+     */
     private void removeTimedOutLocks(long timeout)
     {
         int count = 0;
@@ -377,7 +383,7 @@
         List list = (List) keyLockMap.get(key);
         if(list == null)
         {
-            list = new TreeList();
+            list = new ArrayList();
             keyLockMap.put(key, list);
         }
         if(!list.contains(lock)) list.add(lock);

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/ArgumentDescriptor.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/ArgumentDescriptor.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/ArgumentDescriptor.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/ArgumentDescriptor.java Fri Jan 12 10:19:39 2007
@@ -15,11 +15,10 @@
  * limitations under the License.
  */
 
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
-import org.apache.ojb.broker.accesslayer.conversions.FieldConversion;
 import java.io.Serializable;
 
+import org.apache.ojb.broker.accesslayer.conversions.FieldConversion;
+
 /**
  * An ArgumentDescriptor contains information that defines a single argument
  * that is passed to a procedure/function.
@@ -41,7 +40,8 @@
     private int fieldSource = SOURCE_NULL;
     private String constantValue = null;
     private String fieldRefName = null;
-    private boolean returnedByProcedure = false;
+    private boolean inParameter = true;
+    private boolean outParameter = false;
 
     //---------------------------------------------------------------
     /**
@@ -70,9 +70,12 @@
      */
     public void setValue()
     {
+        verifyValueSetting();
+
         this.fieldSource = SOURCE_NULL;
         this.fieldRefName = null;
-        this.returnedByProcedure = false;
+        this.inParameter = true;
+        this.outParameter = false;
         this.constantValue = null;
     }
 
@@ -81,10 +84,7 @@
      * in the corresponding class-descriptor.
      * <p>
      * If the value of <code>fieldRefName</code> is blank or refers to an
-     * invalid field reference, then the value of the corresponding argument
-     * will be set to null. In this case, {@link #getIsReturnedByProcedure}
-     * will be set to <code>false</code>, regardless of the value of the
-     * <code>returnedByProcedure</code> argument.
+     * invalid field reference a runtime exception will be thrown..
      *
      * @param fieldRefName the name of the field reference that provides the
      *          value of this argument.
@@ -93,23 +93,21 @@
      */
     public void setValue(String fieldRefName, boolean returnedByProcedure)
     {
+        verifyValueSetting();
+
         this.fieldSource = SOURCE_FIELD;
         this.fieldRefName = fieldRefName;
-        this.returnedByProcedure = returnedByProcedure;
+        this.inParameter = !returnedByProcedure;
+        this.outParameter = returnedByProcedure;
         this.constantValue = null;
 
         // If the field reference is not valid, then disregard the value
         // of the returnedByProcedure argument.
         if (this.getFieldRef() == null)
         {
-            this.returnedByProcedure = false;
-        }
-
-        // If the field reference is not valid, then disregard the value
-        // of the returnedByProcedure argument.
-        if (this.getFieldRef() == null)
-        {
-            this.returnedByProcedure = false;
+            throw new MetadataException("Can't resolve field name '" + fieldRefName
+                    + "' for " + getProcedureDescriptor().getClassDescriptor().getClassOfObject()
+                    + " in this argument descriptor");
         }
     }
 
@@ -121,20 +119,18 @@
      */
     public void setValue(String constantValue)
     {
+        verifyValueSetting();
+
         this.fieldSource = SOURCE_VALUE;
         this.fieldRefName = null;
-        this.returnedByProcedure = false;
+        this.inParameter = true;
+        this.outParameter = false;
         this.constantValue = constantValue;
     }
 
-    public boolean getIsReturnedByProcedure()
-    {
-        return this.returnedByProcedure;
-    }
-
     public Object getValue(Object objekt)
     {
-        switch (this.fieldSource)
+        switch (fieldSource)
         {
             case SOURCE_FIELD :
                 if (objekt == null)
@@ -166,26 +162,26 @@
         }
     }
 
-    public void saveValue(Object objekt, Object value)
-    {
-        if ((this.fieldSource == SOURCE_FIELD) && (this.returnedByProcedure))
-        {
-            FieldDescriptor fd = this.getFieldRef();
-            FieldConversion conversion;
-            if (fd != null)
-            {
-                conversion = fd.getFieldConversion();
-                if (conversion == null)
-                {
-                    fd.getPersistentField().set(objekt, value);
-                }
-                else
-                {
-                    fd.getPersistentField().set(objekt, conversion.sqlToJava(value));
-                }
-            }
-        }
-    }
+//    public void saveValue(Object objekt, Object value)
+//    {
+//        if ((this.fieldSource == SOURCE_FIELD) && (this.returnedByProcedure))
+//        {
+//            FieldDescriptor fd = this.getFieldRef();
+//            FieldConversion conversion;
+//            if (fd != null)
+//            {
+//                conversion = fd.getFieldConversion();
+//                if (conversion == null)
+//                {
+//                    fd.getPersistentField().set(objekt, value);
+//                }
+//                else
+//                {
+//                    fd.getPersistentField().set(objekt, conversion.sqlToJava(value));
+//                }
+//            }
+//        }
+//    }
 
     /**
      * Retrieve the field name that this argument is related to.
@@ -221,18 +217,18 @@
      * Retrieve the jdbc type for the field descriptor that is related
      * to this argument.
      */
-    public final int getJdbcType()
+    public final JdbcType getJdbcType()
     {
         switch (this.fieldSource)
         {
             case SOURCE_FIELD :
-                return this.getFieldRef().getJdbcType().getType();
+                return this.getFieldRef().getJdbcType();
             case SOURCE_NULL :
-                return java.sql.Types.NULL;
+                return new JdbcTypes.T_Null();
             case SOURCE_VALUE :
-                return java.sql.Types.VARCHAR;
+                return new JdbcTypes.T_Varchar();
             default :
-                return java.sql.Types.NULL;
+                throw new MetadataException("Can't determine jdbc field type, please check metadata setting");
         }
     }
 
@@ -247,6 +243,29 @@
         return this.procedureDescriptor;
     }
 
+    public boolean isInParameter()
+    {
+        return inParameter;
+    }
+
+    public boolean isOutParameter()
+    {
+        return outParameter;
+    }
+
+    public boolean isConstant()
+    {
+        return constantValue != null;
+    }
+
+    private void verifyValueSetting()
+    {
+        if(isConstant())
+        {
+            throw new MetadataException("It's not allwed to change the type/value of an argument");
+        }
+    }
+
     /*
      * @see XmlCapable#toXML()
      */
@@ -262,7 +281,7 @@
             case SOURCE_FIELD :
                 result += " " + RepositoryTags.getOpeningTagNonClosingById(RUNTIME_ARGUMENT);
                 result += " " + RepositoryTags.getAttribute(FIELD_REF, this.fieldRefName);
-                result += " " + RepositoryTags.getAttribute(RETURN, String.valueOf(this.returnedByProcedure));
+                result += " " + RepositoryTags.getAttribute(RETURN, String.valueOf(this.outParameter));
                 result += "/>";
                 break;
             case SOURCE_VALUE :
@@ -290,25 +309,29 @@
      */
     public String toString()
     {
-        ToStringBuilder buf = new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE);
+        StringBuffer buf = new StringBuffer();
+        buf.append("arg[");
         switch (this.fieldSource)
         {
             case SOURCE_FIELD :
                 {
-                    buf.append("fieldRefName", this.fieldRefName);
-                    buf.append("returnedByProcedure", this.returnedByProcedure);
+                    buf.append("fieldRefName=").append(this.fieldRefName);
+                    buf.append(", inParameter=").append(this.inParameter);
+                    buf.append(", outParameter=").append(this.outParameter);
                     break;
                 }
             case SOURCE_NULL :
                 {
+                    buf.append("null");
                     break;
                 }
             case SOURCE_VALUE :
                 {
-                    buf.append("constantValue", this.constantValue);
+                    buf.append("constant=").append(this.constantValue);
                     break;
                 }
         }
+        buf.append("]");
         return buf.toString();
     }
 }

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/AttributeContainer.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/AttributeContainer.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/AttributeContainer.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/AttributeContainer.java Fri Jan 12 10:19:39 2007
@@ -53,8 +53,13 @@
     public Properties getAttributes();
 
     /**
-     * Add map of attributes.
+     * Set attributes.
      */
-    public void addAttributes(Map attributes);
+    public void setAttributes(Properties attributes);
+
+    /**
+     * Add attributes.
+     */
+    public void addAttributes(Properties attributes);
 }
 

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/AttributeDescriptorBase.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/AttributeDescriptorBase.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/AttributeDescriptorBase.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/AttributeDescriptorBase.java Fri Jan 12 10:19:39 2007
@@ -70,11 +70,6 @@
     {
         return m_ClassDescriptor;
     }
-
-    protected ClassDescriptor getDescriptorFor(Class aClass)
-    {
-        return getClassDescriptor().getRepository().getDescriptorFor(aClass);
-    }
     
     /**
      * Sets the classDescriptor.

Modified: db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/BatchDescriptor.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/BatchDescriptor.java?view=diff&rev=495677&r1=495676&r2=495677
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/BatchDescriptor.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/broker/metadata/BatchDescriptor.java Fri Jan 12 10:19:39 2007
@@ -5,6 +5,7 @@
 import org.apache.ojb.broker.accesslayer.batch.BatchManagerImpl;
 import org.apache.ojb.broker.accesslayer.batch.BatchStrategyDefaultImpl;
 import org.apache.ojb.broker.accesslayer.batch.ReturnValueValidatorImpl;
+import org.apache.ojb.broker.util.XmlHelper;
 
 /* Copyright 2002-2004 The Apache Software Foundation
  *
@@ -127,11 +128,12 @@
         buf.append(eol);
         buf.append("         Add sequence manger properties here, using custom attributes");
         buf.append(eol);
-        buf.append("         e.g. <attribute attribute-name=\"grabSize\" attribute-value=\"20\"/>");
+        buf.append("         e.g. <attribute attribute-name=\"aKey\" attribute-value=\"aValue\"/>");
         buf.append(eol);
         buf.append("         -->");
         buf.append(eol);
-        buf.append(super.toXML("         "));
+        // custom attributes
+        XmlHelper.appendSerializedAttributes(buf, "        ", getAttributes());
         buf.append("      ");
         buf.append(RepositoryTags.getClosingTagById(BATCH));
         buf.append(eol);



---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message