openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jrba...@apache.org
Subject svn commit: r1335720 [1/5] - in /openjpa/branches/2.2.x: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ openjpa-jdbc/sr...
Date Tue, 08 May 2012 19:46:23 GMT
Author: jrbauer
Date: Tue May  8 19:46:20 2012
New Revision: 1335720

URL: http://svn.apache.org/viewvc?rev=1335720&view=rev
Log:
OPENJPA-2165 Ported code and tests back to 2.2.x branch

Added:
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedArrayListProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedCollectionChangeTrackerImpl.java   (with props)
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedHashSetProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedLinkedHashSetProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedLinkedListProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedPriorityQueueProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedTreeSetProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedVectorProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/Award.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/Certification.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/DelayedProxyCollectionsTestCase.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/IAccount.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/IDepartment.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/IEmployee.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/IMember.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/IUserIdentity.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/Location.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/Product.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/alist/
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/alist/Account.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/alist/Department.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/alist/Employee.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/alist/Member.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/alist/TestDelayedArrayListProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/alist/TestDelayedArrayListProxyDetachLite.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/alist/UserIdentity.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/hset/
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/hset/Account.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/hset/Department.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/hset/Employee.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/hset/Member.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/hset/TestDelayedHashSetProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/hset/TestDelayedHashSetProxyDetachLite.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/hset/UserIdentity.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/lhset/
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/lhset/Account.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/lhset/Department.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/lhset/Employee.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/lhset/Member.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/lhset/TestDelayedLinkedHashSetProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/lhset/TestDelayedLinkedHashSetProxyDetachLite.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/lhset/UserIdentity.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/llist/
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/llist/Account.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/llist/Department.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/llist/Employee.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/llist/Member.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/llist/TestDelayedLinkedListProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/llist/TestDelayedLinkedListProxyDetachLite.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/llist/UserIdentity.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/pqueue/
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/pqueue/Account.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/pqueue/Department.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/pqueue/Employee.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/pqueue/Member.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/pqueue/TestDelayedPriorityQueueProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/pqueue/TestDelayedPriorityQueueProxyDetachLite.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/pqueue/UserIdentity.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/tset/
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/tset/Account.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/tset/Department.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/tset/Employee.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/tset/Member.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/tset/TestDelayedTreeSetProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/tset/TestDelayedTreeSetProxyDetachLite.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/tset/UserIdentity.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/vec/
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/vec/Account.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/vec/Department.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/vec/Employee.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/vec/Member.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/vec/TestDelayedVectorProxy.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/vec/TestDelayedVectorProxyDetachLite.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/proxy/delayed/vec/UserIdentity.java   (with props)
Modified:
    openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
    openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
    openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
    openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java
    openjpa/branches/2.2.x/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestUpdateManagerFlushException.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/OpenJPAStateManager.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/CollectionChangeTrackerImpl.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyCollections.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManager.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java

Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java (original)
+++ openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java Tue May  8 19:46:20 2012
@@ -242,7 +242,7 @@ public class JDBCStoreManager implements
     }
     
     protected DataSource getDataSource() {
-    	return _ds;
+        return _ds;
     }
 
     public boolean exists(OpenJPAStateManager sm, Object context) {
@@ -641,31 +641,37 @@ public class JDBCStoreManager implements
                 && mapping.customLoad(sm, this, null, jfetch))
                 removeLoadedFields(sm, fields);
 
+            
             //### select is kind of a big object, and in some cases we don't
             //### use it... would it be worth it to have a small shell select
             //### object that only creates a real select when actually used?
-
-            Select sel = _sql.newSelect();
-            if (select(sel, mapping, Select.SUBS_EXACT, sm, fields, jfetch,
-                EagerFetchModes.EAGER_JOIN, true, false)) {
-                sel.wherePrimaryKey(sm.getObjectId(), mapping, this);
-                if (_log.isTraceEnabled()) {
-                    _log.trace("load: "+mapping.getDescribedType()+" oid: "+sm.getObjectId()); 
-                }
-                res = sel.execute(this, jfetch, lockLevel);
-                try {
-                 	if (isEmptyResult(res))
-                        return false;
-                    load(mapping, sm, jfetch, res);
-                } finally {
-                    res.close();
-                }
+            //### Delayed proxy specific optimization: If the only fields that 
+            //### need to be loaded are delayed proxies, building the select is 
+            //### not necessary.
+
+            if (!isDelayedLoadOnly(sm, fields, mapping)) {
+	            Select sel = _sql.newSelect();
+	            if (select(sel, mapping, Select.SUBS_EXACT, sm, fields, jfetch,
+	                EagerFetchModes.EAGER_JOIN, true, false)) {
+	                sel.wherePrimaryKey(sm.getObjectId(), mapping, this);
+	                if (_log.isTraceEnabled()) {
+	                    _log.trace("load: "+mapping.getDescribedType()+" oid: "+sm.getObjectId()); 
+	                }
+	                res = sel.execute(this, jfetch, lockLevel);
+	                try {
+	                    if (isEmptyResult(res))
+	                        return false;
+	                    load(mapping, sm, jfetch, res);
+	                } finally {
+	                    res.close();
+	                }
+	            }
             }
 
             // now allow the fields to load themselves individually too
             FieldMapping[] fms = mapping.getFieldMappings();
             for (int i = 0; i < fms.length; i++)
-                if (fields.get(i) && !sm.getLoaded().get(i)) {
+                if (fields.get(i) && (!sm.getLoaded().get(i) || sm.isDelayed(i))) {
                     if (_log.isTraceEnabled()) {
                         _log.trace("load field: '"+ fms[i].getName() + "' for oid="+sm.getObjectId()
                             +" "+mapping.getDescribedType());
@@ -681,6 +687,22 @@ public class JDBCStoreManager implements
         }
     }
 
+    private boolean isDelayedLoadOnly(OpenJPAStateManager sm, BitSet fields, ClassMapping mapping) {
+        if (!sm.getContext().getConfiguration().getProxyManagerInstance().getDelayCollectionLoading() 
+            || fields.isEmpty()) {
+            return false;
+        }
+        FieldMapping[] fms = mapping.getFieldMappings();
+        for (int i = 0; i < fms.length; i++) {
+            if (fields.get(i)) {
+                if (!(fms[i].isDelayCapable() && (!sm.getLoaded().get(i) || sm.isDelayed(i)))) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+    
     /**
      * Return a list formed by removing all loaded fields from the given one.
      */
@@ -1080,10 +1102,10 @@ public class JDBCStoreManager implements
                         eagerToMany = fms[i];
                     else
                         fms[i].loadEagerJoin(sm, this, 
-                        	fetch.traverseJDBC(fms[i]), res);
+                            fetch.traverseJDBC(fms[i]), res);
                 } else if (eres != null) {
                     processed = fms[i].loadEagerParallel(sm, this, 
-                    	fetch.traverseJDBC(fms[i]), eres);
+                        fetch.traverseJDBC(fms[i]), eres);
                     if (processed != eres)
                         res.putEager(fms[i], processed);
                 } else {
@@ -1332,18 +1354,18 @@ public class JDBCStoreManager implements
             if (esel != null) {
                 if (esel == sel)
                     fms[i].selectEagerJoin(sel, sm, this, 
-                    	fetch.traverseJDBC(fms[i]), eager);
+                        fetch.traverseJDBC(fms[i]), eager);
                 else
                     fms[i].selectEagerParallel(esel, sm, this, 
-                    	fetch.traverseJDBC(fms[i]), eager);
+                        fetch.traverseJDBC(fms[i]), eager);
                 seld = Math.max(0, seld);
             } else if (requiresSelect(fms[i], sm, fields, fetch)) {
                 fseld = fms[i].select(sel, sm, this, 
-                	fetch.traverseJDBC(fms[i]), eager);
+                    fetch.traverseJDBC(fms[i]), eager);
                 seld = Math.max(fseld, seld);
             } else if (optSelect(fms[i], sel, sm, fetch)) {
                 fseld = fms[i].select(sel, sm, this, 
-                	fetch.traverseJDBC(fms[i]), EagerFetchModes.EAGER_NONE);
+                    fetch.traverseJDBC(fms[i]), EagerFetchModes.EAGER_NONE);
 
                 // don't upgrade seld to > 0 based on these fields, since
                 // they're not in the calculated field set
@@ -1425,12 +1447,12 @@ public class JDBCStoreManager implements
             fms = subMappings[i].getDefinedFieldMappings();
             for (int j = 0; j < fms.length; j++) {
                 // make sure in one of configured fetch groups
-            	if (fetch.requiresFetch(fms[j]) != FetchConfiguration.FETCH_LOAD
+                if (fetch.requiresFetch(fms[j]) != FetchConfiguration.FETCH_LOAD
                     && ((!fms[j].isInDefaultFetchGroup() 
                     && fms[j].isDefaultFetchGroupExplicit())
                     || fms[j].supportsSelect(sel, Select.TYPE_TWO_PART, sm, this, 
                     fetch) <= 0)) 
-            		continue;
+                    continue;
 
                 // if we can join to the subclass, do so; much better chance
                 // that the field will be able to select itself without joins

Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java (original)
+++ openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java Tue May  8 19:46:20 2012
@@ -1359,4 +1359,9 @@ public class FieldMapping
     public boolean hasMapsIdCols() {
         return _hasMapsIdCols;
     }
+    
+    @Override
+    public boolean isDelayCapable() {
+        return (getOrderColumn() == null && !isInDefaultFetchGroup() && super.isDelayCapable());
+    }
 }

Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java (original)
+++ openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java Tue May  8 19:46:20 2012
@@ -1252,6 +1252,21 @@ public class EmbedFieldStrategy
         public Object replaceObjectField(PersistenceCapable pc, int field) {
             throw new InternalException();
         }
+
+        @Override
+        public boolean isDelayed(int field) {
+            return false;
+        }
+        
+        @Override
+        public void setDelayed(int field, boolean delay) {
+            throw new InternalException();
+        }
+        
+        @Override
+        public void loadDelayedField(int field) {
+            throw new UnsupportedOperationException();
+        }
     }
 
     /**

Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java (original)
+++ openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java Tue May  8 19:46:20 2012
@@ -25,6 +25,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.openjpa.enhance.FieldManager;
 import org.apache.openjpa.enhance.PersistenceCapable;
 import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
 import org.apache.openjpa.jdbc.kernel.JDBCStore;
@@ -42,13 +43,13 @@ import org.apache.openjpa.jdbc.sql.Selec
 import org.apache.openjpa.jdbc.sql.Union;
 import org.apache.openjpa.kernel.OpenJPAStateManager;
 import org.apache.openjpa.kernel.StateManagerImpl;
-import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.JavaTypes;
 import org.apache.openjpa.util.ChangeTracker;
 import org.apache.openjpa.util.Id;
 import org.apache.openjpa.util.OpenJPAId;
 import org.apache.openjpa.util.Proxy;
+import org.apache.openjpa.util.DelayedProxy;
 
 /**
  * Base class for strategies that are stored as a collection, even if
@@ -491,8 +492,21 @@ public abstract class StoreCollectionFie
     public void load(final OpenJPAStateManager sm, final JDBCStore store,
         final JDBCFetchConfiguration fetch)
         throws SQLException {
+        
+        Object coll = null;
+        final int fieldIndex = field.getIndex();
+        final boolean delayed = sm.isDelayed(fieldIndex);
+        if (!delayed && field.isDelayCapable()) {
+            coll = sm.newProxy(fieldIndex);
+            if (coll instanceof DelayedProxy) {
+                sm.storeObject(fieldIndex, coll);
+                sm.setDelayed(fieldIndex, true);
+                return;
+            }
+        }
+        
         if (field.isLRS()) {
-            Proxy coll = newLRSProxy();
+            Proxy pcoll = newLRSProxy();
 
             // if this is ordered we need to know the next seq to use in case
             // objects are added to the collection
@@ -513,13 +527,13 @@ public abstract class StoreCollectionFie
                 Result res = sel.execute(store, fetch);
                 try {
                     res.next();
-                    coll.getChangeTracker().setNextSequence
+                    pcoll.getChangeTracker().setNextSequence
                         (res.getInt(field) + 1);
                 } finally {
                     res.close();
                 }
             }
-            sm.storeObjectField(field.getIndex(), coll);
+            sm.storeObjectField(fieldIndex, pcoll);
             return;
         }
 
@@ -537,14 +551,27 @@ public abstract class StoreCollectionFie
         });
 
         // create proxy
-        Object coll;
         ChangeTracker ct = null;
-        if (field.getTypeCode() == JavaTypes.ARRAY)
-            coll = new ArrayList();
-        else {
-            coll = sm.newProxy(field.getIndex());
+        if (delayed) {
+            if (sm.isDetached() || sm.getOwner() == null) {
+                sm.getPersistenceCapable().pcProvideField(fieldIndex);
+                coll = 
+                    ((FieldManager)sm.getPersistenceCapable().pcGetStateManager()).fetchObjectField(fieldIndex);
+            } else {
+                coll = sm.fetchObjectField(fieldIndex);
+            }
             if (coll instanceof Proxy)
                 ct = ((Proxy) coll).getChangeTracker();
+        } else {
+            if (field.getTypeCode() == JavaTypes.ARRAY)
+                coll = new ArrayList();
+            else {
+                if (coll == null) {
+                    coll = sm.newProxy(fieldIndex);
+                }
+                if (coll instanceof Proxy)
+                    ct = ((Proxy) coll).getChangeTracker();
+            }
         }
 
         // load values
@@ -564,12 +591,14 @@ public abstract class StoreCollectionFie
             res.close();
         }
 
-        // set into sm
-        if (field.getTypeCode() == JavaTypes.ARRAY)
-            sm.storeObject(field.getIndex(), JavaTypes.toArray
-                ((Collection) coll, field.getElement().getType()));
-        else
-            sm.storeObject(field.getIndex(), coll);
+        // if not a delayed collection, set into sm
+        if (!delayed) {
+            if (field.getTypeCode() == JavaTypes.ARRAY)
+                sm.storeObject(fieldIndex, JavaTypes.toArray
+                    ((Collection) coll, field.getElement().getType()));
+            else
+                sm.storeObject(fieldIndex, coll);
+        }
     }
 
     /**

Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestUpdateManagerFlushException.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestUpdateManagerFlushException.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestUpdateManagerFlushException.java (original)
+++ openjpa/branches/2.2.x/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestUpdateManagerFlushException.java Tue May  8 19:46:20 2012
@@ -690,6 +690,18 @@ public class TestUpdateManagerFlushExcep
         public String fetchStringField(int fieldIndex) {
             return null;
         }
+
+        @Override
+        public boolean isDelayed(int field) {
+            return false;
+        }
+
+        @Override
+        public void setDelayed(int field, boolean delay) {
+        }
+
+        public void loadDelayedField(int field) {
+        }
     }
 
     /*

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java (original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java Tue May  8 19:46:20 2012
@@ -995,4 +995,19 @@ public class DetachedStateManager
         if (_lock != null)
             _lock.unlock();
     }
+    
+    @Override
+    public boolean isDelayed(int field) {
+        return false;
+    }
+    
+    @Override
+    public void setDelayed(int field, boolean delay) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void loadDelayedField(int field) {
+        throw new UnsupportedOperationException();
+    }
 }

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java (original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java Tue May  8 19:46:20 2012
@@ -595,5 +595,20 @@ public class DetachedValueStateManager
     public Object replaceObjectField(PersistenceCapable pc, int idx) {
         throw new UnsupportedOperationException();
     }
+    
+    @Override
+    public boolean isDelayed(int field) {
+        return false;
+    }
+    
+    @Override
+    public void setDelayed(int field, boolean delay) {
+        throw new UnsupportedOperationException();
+    }
+    
+    @Override
+    public void loadDelayedField(int field) {
+        throw new UnsupportedOperationException();
+    }
 }
 

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java (original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java Tue May  8 19:46:20 2012
@@ -739,4 +739,19 @@ public class ObjectIdStateManager
             Reflection.set(_oid, Reflection.findSetter(_oid.getClass(),
                 fmd.getName(), fmd.getDeclaredType(), true), val);
 	}
+    
+    @Override
+    public boolean isDelayed(int field) {
+        return false;
+    }
+
+    @Override
+    public void setDelayed(int field, boolean delay) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void loadDelayedField(int field) {
+        throw new UnsupportedOperationException();
+    }
 }

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/OpenJPAStateManager.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/OpenJPAStateManager.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/OpenJPAStateManager.java (original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/OpenJPAStateManager.java Tue May  8 19:46:20 2012
@@ -498,5 +498,37 @@ public interface OpenJPAStateManager
      * @since 0.3.1
      */
     public void setRemote (int field, Object value);
+    
+    /**
+     * Some field types (collection proxies) support delayed loading.  Delayed loading
+     * is a step beyond lazy loading.  Delayed load allows an instance of a field to be 
+     * returned without actually loading it.
+     * 
+     * @param field
+     * @return true if the field is setup for delayed access
+     */
+    public boolean isDelayed(int field);
+    
+    /**
+     * Some field types (collection proxies) support delayed loading.  Delayed loading
+     * is a step beyond lazy loading.  Delayed load allows an instance of a field to be 
+     * returned without actually loading it.
+     * 
+     * @param field
+     */
+    public void setDelayed(int field, boolean delay);
+    
+    /**
+     * If a field was marked delayed in a previous load operation this method can be
+     * used to load the field.
+     * @param field
+     */
+    public void loadDelayedField(int field);
+    
+    /**
+     * Fetch an object field by index.
+     * @param field
+     */
+    public Object fetchObjectField(int field);
 }
 

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Tue May  8 19:46:20 2012
@@ -118,6 +118,7 @@ public class StateManagerImpl
     protected BitSet _loaded = null;
     private BitSet _dirty = null;
     private BitSet _flush = null;
+    private BitSet _delayed = null;
     private int _flags = 0;
 
     // id is the state manager identity; oid is the persistent identity.  oid
@@ -1600,6 +1601,58 @@ public class StateManagerImpl
         }
     }
 
+    public boolean isDelayed(int field) {
+        if (_delayed == null) {
+            return false;
+        }
+        return _delayed.get(field);
+    }
+
+    public void setDelayed(int field, boolean delay) {
+        if (_delayed == null) {
+            _delayed = new BitSet();
+        }
+        if (delay) {
+            _delayed.set(field);
+        } else {
+            _delayed.clear(field);
+        }
+    }
+
+    /**
+     * Loads a delayed access field.
+     * @param field
+     */
+    public void loadDelayedField(int field) {
+        if (!isDelayed(field)) {
+            return;
+        }
+
+        try {
+            beforeRead(field);
+        } catch (RuntimeException re) {
+            throw translate(re);
+        }
+        lock();
+        try {
+            boolean active = _broker.isActive();
+            int lockLevel = calculateLockLevel(active, false, null);
+            BitSet fields = new BitSet();
+            fields.set(field);
+            if (!_broker.getStoreManager().load(this, fields, _broker.getFetchConfiguration(), lockLevel, null)) {
+                throw new ObjectNotFoundException(_loc.get("del-instance", _meta.getDescribedType(), _oid)).
+                    setFailedObject(getManagedInstance());
+            }
+            // Cleared the delayed bit
+            _delayed.clear(field);
+            obtainLocks(active, false, lockLevel, null, null);
+        } catch (RuntimeException re) {
+            throw translate(re);
+        } finally {
+            unlock();
+        }
+    }
+
     /**
      * Load the given field before access.
      */
@@ -3420,4 +3473,8 @@ public class StateManagerImpl
     public void setPc(PersistenceCapable pc) {
         _pc = pc;
     }
+
+    public void setBroker(BrokerImpl ctx) {
+        _broker = ctx;
+    }
 }

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java (original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java Tue May  8 19:46:20 2012
@@ -61,6 +61,7 @@ import org.apache.openjpa.util.Exception
 import org.apache.openjpa.util.InternalException;
 import org.apache.openjpa.util.MetaDataException;
 import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.util.ProxyManager;
 import org.apache.openjpa.util.UnsupportedException;
 import org.apache.openjpa.util.ImplHelper;
 import org.apache.openjpa.util.UserException;
@@ -222,6 +223,7 @@ public class FieldMetaData
 
     private boolean _persistentCollection = false; 
 
+    private Boolean _delayCapable = null;
     /**
      * Constructor.
      *
@@ -2405,4 +2407,27 @@ public class FieldMetaData
     	return _relationType;
     }
     private class Unknown{};
+    
+    public boolean isDelayCapable() {
+        if (_delayCapable != null) {
+            return _delayCapable.booleanValue();
+        }
+        if (getTypeCode() != JavaTypes.COLLECTION || isLRS()) {
+           _delayCapable = Boolean.FALSE;
+           return _delayCapable;
+        } else {
+            // Verify the proxy manager is configured to handle delay loading
+            ProxyManager pm = getRepository().getConfiguration().getProxyManagerInstance();
+            if (pm != null) {
+                _delayCapable = pm.getDelayCollectionLoading();
+            } else {
+                _delayCapable = Boolean.FALSE;
+            }
+        }
+        return _delayCapable;
+    }
+    
+    public void setDelayCapable(Boolean delayCapable) {
+        _delayCapable = delayCapable;
+    }
 }

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/CollectionChangeTrackerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/CollectionChangeTrackerImpl.java?rev=1335720&r1=1335719&r2=1335720&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/CollectionChangeTrackerImpl.java (original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/CollectionChangeTrackerImpl.java Tue May  8 19:46:20 2012
@@ -31,9 +31,9 @@ public class CollectionChangeTrackerImpl
     extends AbstractChangeTracker
     implements CollectionChangeTracker {
 
-    private final Collection _coll;
-    private final boolean _dups;
-    private final boolean _order;
+    protected final Collection _coll;
+    protected final boolean _dups;
+    protected final boolean _order;
 
     /**
      * Constructor.

Added: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedArrayListProxy.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedArrayListProxy.java?rev=1335720&view=auto
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedArrayListProxy.java (added)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedArrayListProxy.java Tue May  8 19:46:20 2012
@@ -0,0 +1,447 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.util;
+
+import java.io.ObjectStreamException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.openjpa.kernel.AutoDetach;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.DetachedStateManager;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+
+/**
+ * ArrayList proxy with delay loading capability.  Allows non-indexed
+ * add and remove operations to occur on an unloaded collection.  Operations
+ * that require a load will trigger a load.
+ */
+@SuppressWarnings({"rawtypes","unchecked"})
+public class DelayedArrayListProxy extends ArrayList implements ProxyCollection, DelayedProxy {
+
+    private transient OpenJPAStateManager sm;
+    private transient int field;
+    private transient CollectionChangeTracker changeTracker;
+    private transient Class<?> elementType;
+    private transient OpenJPAStateManager _ownerSm;
+    private transient boolean _directAccess = false;
+    private transient BrokerFactory _brokerFactory = null;
+    private transient Broker _broker = null;
+    private transient OpenJPAStateManager _delayedSm;
+    private transient int _delayedField;
+    private transient boolean _detached = false;
+
+    public DelayedArrayListProxy() {
+    }
+
+    public DelayedArrayListProxy(Collection paramCollection) {
+        super(paramCollection);
+    }
+
+    public DelayedArrayListProxy(int paramInt) {
+        super(paramInt);
+    }
+
+    public void setOwner(OpenJPAStateManager paramOpenJPAStateManager,
+            int paramInt) {
+        // If clearing the owner of this proxy, store away what is necessary for
+        // delayed loading
+        if (sm != null && detaching(paramOpenJPAStateManager, paramInt)) {
+            _detached = true;
+            _delayedSm = sm;
+            _delayedField = field;
+        } else {
+            _detached = false;
+        }
+
+        this.sm = paramOpenJPAStateManager;
+        if (sm != null && sm.getPersistenceCapable() != null) {
+            _ownerSm = (OpenJPAStateManager) sm.getPersistenceCapable()
+                    .pcGetStateManager();
+        }
+        this.field = paramInt;
+        if (sm != null && sm.getContext() != null) {
+            _brokerFactory = sm.getContext().getBroker().getBrokerFactory();
+        }
+    }
+
+    private boolean detaching(OpenJPAStateManager paramOpenJPAStateManager,
+            int paramInt) {
+        if ((paramOpenJPAStateManager == null && paramInt == -1)
+                || (paramOpenJPAStateManager != null && paramOpenJPAStateManager instanceof DetachedStateManager)) {
+            return true;
+        }
+        return false;
+    }
+
+    public int getDelayedField() {
+        if (field == -1 || _detached) {
+            return _delayedField;
+        }
+        return field;
+    }
+
+    public OpenJPAStateManager getDelayedOwner() {
+        if (sm == null || _detached) {
+            return _delayedSm;
+        }
+        return sm;
+    }
+
+    public OpenJPAStateManager getOwner() {
+        return sm;
+    }
+
+    public int getOwnerField() {
+        return field;
+    }
+
+    public Object clone() {
+        if (isDirectAccess()) {
+            return super.clone();
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        Proxy localProxy = (Proxy) super.clone();
+        localProxy.setOwner(null, 0);
+        return localProxy;
+    }
+
+    public ChangeTracker getChangeTracker() {
+        return this.changeTracker;
+    }
+
+    protected void setChangeTracker(CollectionChangeTracker ct) {
+        changeTracker = ct;
+    }
+
+    public Object copy(Object paramObject) {
+        if (isDelayLoad()) {
+            load();
+        }
+        return new ArrayList((Collection) paramObject);
+    }
+
+    public Class getElementType() {
+        return this.elementType;
+    }
+
+    protected void setElementType(Class<?> elemType) {
+        elementType = elemType;
+    }
+
+    @Override
+    public ProxyCollection newInstance(Class paramClass,
+            Comparator paramComparator, boolean paramBoolean1,
+            boolean paramBoolean2) {
+        DelayedArrayListProxy proxy = new DelayedArrayListProxy();
+        proxy.elementType = paramClass;
+        proxy.changeTracker = new DelayedCollectionChangeTrackerImpl(proxy,
+                true, true, paramBoolean2);
+        return proxy;
+    }
+
+    public boolean add(Object paramObject) {
+        if (_directAccess) {
+            return super.add(paramObject);
+        }
+        ProxyCollections.beforeAdd(this, paramObject);
+        boolean bool = super.add(paramObject);
+        return ProxyCollections.afterAdd(this, paramObject, bool);
+    }
+
+    public void add(int paramInt, Object paramObject) {
+        if (!_directAccess) {
+            if (isDelayLoad()) {
+                load();
+            }
+        }
+        ProxyCollections.beforeAdd(this, paramInt, paramObject);
+        super.add(paramInt, paramObject);
+    }
+
+    public void clear() {
+        if (!_directAccess) {
+            if (isDelayLoad()) {
+                load();
+            }
+            ProxyCollections.beforeClear(this);
+        }
+        super.clear();
+    }
+
+    public boolean addAll(int paramInt, Collection paramCollection) {
+        if (isDelayLoad()) {
+            load();
+        }
+        return ProxyCollections.addAll(this, paramInt, paramCollection);
+    }
+
+    public boolean addAll(Collection paramCollection) {
+        if (_directAccess) {
+            return super.addAll(paramCollection);
+        }
+        return ProxyCollections.addAll(this, paramCollection);
+    }
+
+    public boolean remove(Object paramObject) {
+        if (_directAccess) {
+            return super.remove(paramObject);
+        }
+        ProxyCollections.beforeRemove(this, paramObject);
+        setDirectAccess(true);
+        boolean bool = super.remove(paramObject);
+        setDirectAccess(false);
+        return ProxyCollections.afterRemove(this, paramObject, bool);
+    }
+
+    public Object remove(int paramInt) {
+        if (_directAccess) {
+            return super.remove(paramInt);
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        ProxyCollections.beforeRemove(this, paramInt);
+        Object localObject = super.remove(paramInt);
+        return ProxyCollections.afterRemove(this, paramInt, localObject);
+    }
+
+    public Object set(int paramInt, Object paramObject) {
+        if (_directAccess) {
+            return super.set(paramInt, paramObject);
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        ProxyCollections.beforeSet(this, paramInt, paramObject);
+        Object localObject = super.set(paramInt, paramObject);
+        return ProxyCollections.afterSet(this, paramInt, paramObject,
+                localObject);
+    }
+
+    public Iterator iterator() {
+        if (_directAccess) {
+            return super.iterator();
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        Iterator localIterator = super.iterator();
+        return ProxyCollections.afterIterator(this, localIterator);
+    }
+
+    public ListIterator listIterator(int paramInt) {
+        if (_directAccess) {
+            return super.listIterator(paramInt);
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        ListIterator localListIterator = super.listIterator(paramInt);
+        return ProxyCollections.afterListIterator(this, paramInt,
+                localListIterator);
+    }
+
+    public ListIterator listIterator() {
+        if (_directAccess) {
+            return super.listIterator();
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        ListIterator localListIterator = super.listIterator();
+        return ProxyCollections.afterListIterator(this, localListIterator);
+    }
+
+    public boolean removeAll(Collection paramCollection) {
+        if (_directAccess) {
+            return super.removeAll(paramCollection);
+        }
+        return ProxyCollections.removeAll(this, paramCollection);
+    }
+
+    public boolean retainAll(Collection paramCollection) {
+        if (_directAccess) {
+            return super.retainAll(paramCollection);
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        return ProxyCollections.retainAll(this, paramCollection);
+    }
+
+    protected Object writeReplace() throws ObjectStreamException {
+        if (isDelayLoad()) {
+            load();
+        }
+        return Proxies.writeReplace(this, true);
+    }
+
+    public boolean isDelayLoad() {
+        return ProxyCollections.isDelayed(this);
+    }
+
+    @Override
+    public Object get(int location) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.get(location);
+    }
+
+    @Override
+    public int indexOf(Object object) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.indexOf(object);
+    }
+
+    @Override
+    public int lastIndexOf(Object object) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.lastIndexOf(object);
+    }
+
+    @Override
+    public List subList(int start, int end) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.subList(start, end);
+    }
+
+    @Override
+    public boolean contains(Object object) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.contains(object);
+    }
+
+    @Override
+    public boolean containsAll(Collection collection) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.containsAll(collection);
+    }
+
+    @Override
+    public boolean isEmpty() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.isEmpty();
+    }
+
+    @Override
+    public int size() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.size();
+    }
+
+    @Override
+    public Object[] toArray() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.toArray();
+    }
+
+    @Override
+    public Object[] toArray(Object[] array) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.toArray(array);
+    }
+
+    public boolean equals(Object paramObject) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.equals(paramObject);
+    }
+
+    public int hashCode() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.hashCode();
+    }
+
+    public boolean isDirectAccess() {
+        return _directAccess;
+    }
+
+    public void setDirectAccess(boolean direct) {
+        _directAccess = direct;
+    }
+
+    public BrokerFactory getBrokerFactory() {
+        return _brokerFactory;
+    }
+
+    @Override
+    public void load() {
+        ProxyCollections.loadCollection(this);
+    }
+
+    @Override
+    public Broker getBroker() {
+        if (_broker == null || _broker.isClosed()) {
+            if (_brokerFactory != null) {
+                _broker = _brokerFactory.newBroker();
+            }
+        }
+        return _broker;
+    }
+
+    @Override
+    public void closeBroker() {
+        if (_broker != null && !_broker.isClosed()) {
+            _broker.setAutoDetach(AutoDetach.DETACH_CLOSE);
+            _broker.close();
+            _broker = null;
+        }
+    }
+
+    @Override
+    public OpenJPAStateManager getOwnerStateManager() {
+        return _ownerSm;
+    }
+
+    @Override
+    public boolean isDetached() {
+        return _detached;
+    }
+}
+

Propchange: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedArrayListProxy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedCollectionChangeTrackerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedCollectionChangeTrackerImpl.java?rev=1335720&view=auto
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedCollectionChangeTrackerImpl.java (added)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedCollectionChangeTrackerImpl.java Tue May  8 19:46:20 2012
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * A collection change tracker used by delay loaded collections.
+ *
+ * @nojavadoc
+ */
+public class DelayedCollectionChangeTrackerImpl
+    extends CollectionChangeTrackerImpl {
+
+    public DelayedCollectionChangeTrackerImpl(Collection coll, boolean dups,
+            boolean order,boolean autoOff) {
+        super(coll, dups, order, autoOff);
+    }
+
+    protected void add(Object elem) {
+        if (rem == null || !rem.remove(elem)) {
+            if (add == null) {
+                if (_dups || _order)
+                    add = new ArrayList();
+                else
+                    add = newSet();
+            }
+            add.add(elem);
+        } else {
+            if (change == null)
+                change = newSet();
+            change.add(elem);
+        }
+    }
+
+    protected void remove(Object elem) {
+        if (add == null || !add.remove(elem)) {
+            if (rem == null)
+                rem = newSet();
+            rem.add(elem);
+        }
+    }
+
+    protected void change(Object elem) {
+        throw new InternalException();
+    }
+}

Propchange: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedCollectionChangeTrackerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedHashSetProxy.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedHashSetProxy.java?rev=1335720&view=auto
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedHashSetProxy.java (added)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedHashSetProxy.java Tue May  8 19:46:20 2012
@@ -0,0 +1,362 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.util;
+
+import java.io.ObjectStreamException;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.apache.openjpa.kernel.AutoDetach;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.DetachedStateManager;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+
+/**
+ * HashSet proxy with delay loading capability. Allows non-indexed add and
+ * remove operations to occur on an unloaded collection. Operations that require
+ * a load will trigger a load.
+ */
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public class DelayedHashSetProxy extends HashSet implements DelayedProxy, ProxyCollection {
+
+    private transient OpenJPAStateManager sm;
+    private transient int field;
+    private transient CollectionChangeTracker changeTracker;
+    private transient Class<?> elementType;
+
+    private transient OpenJPAStateManager _ownerSm;
+    private transient boolean _directAccess = false;
+    private transient BrokerFactory _brokerFactory = null;
+    private transient Broker _broker = null;
+    private transient OpenJPAStateManager _delayedSm;
+    private transient int _delayedField;
+    private transient boolean _detached = false;
+
+    public DelayedHashSetProxy(Collection<?> paramCollection) {
+        super(paramCollection);
+    }
+
+    public DelayedHashSetProxy(int paramInt, float paramFloat) {
+        super(paramInt, paramFloat);
+    }
+
+    public DelayedHashSetProxy(int paramInt) {
+        super(paramInt);
+    }
+
+    public DelayedHashSetProxy() {
+    }
+
+    public void setOwner(OpenJPAStateManager paramOpenJPAStateManager,
+            int paramInt) {
+        // If clearing the owner of this proxy, store away what is necessary for
+        // delayed loading
+        if (sm != null && detaching(paramOpenJPAStateManager, paramInt)) {
+            _detached = true;
+            _delayedSm = sm;
+            _delayedField = field;
+        } else {
+            _detached = false;
+        }
+
+        this.sm = paramOpenJPAStateManager;
+        if (sm != null && sm.getPersistenceCapable() != null) {
+            _ownerSm = (OpenJPAStateManager) sm.getPersistenceCapable()
+                    .pcGetStateManager();
+        }
+        this.field = paramInt;
+        if (sm != null && sm.getContext() != null) {
+            _brokerFactory = sm.getContext().getBroker().getBrokerFactory();
+        }
+    }
+
+    private boolean detaching(OpenJPAStateManager paramOpenJPAStateManager,
+            int paramInt) {
+        if ((paramOpenJPAStateManager == null && paramInt == -1)
+                || (paramOpenJPAStateManager != null && paramOpenJPAStateManager instanceof DetachedStateManager)) {
+            return true;
+        }
+        return false;
+    }
+
+    public OpenJPAStateManager getOwner() {
+        return this.sm;
+    }
+
+    public int getOwnerField() {
+        return this.field;
+    }
+
+    public ChangeTracker getChangeTracker() {
+        return this.changeTracker;
+    }
+
+    @Override
+    public Object copy(Object paramObject) {
+        return new HashSet((Collection) paramObject);
+    }
+
+    public Class getElementType() {
+        return this.elementType;
+    }
+
+    public ProxyCollection newInstance(Class paramClass,
+            Comparator paramComparator, boolean paramBoolean1,
+            boolean paramBoolean2) {
+        DelayedHashSetProxy localproxy = new DelayedHashSetProxy();
+        localproxy.elementType = paramClass;
+        if (paramBoolean1)
+            localproxy.changeTracker = new DelayedCollectionChangeTrackerImpl(
+                    localproxy, false, false, paramBoolean2);
+        return localproxy;
+    }
+
+    @Override
+    public Object clone() {
+        if (isDirectAccess()) {
+            return super.clone();
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        Proxy localProxy = (Proxy) super.clone();
+        localProxy.setOwner(null, 0);
+        return localProxy;
+    }
+
+    @Override
+    public boolean add(Object paramObject) {
+        if (_directAccess) {
+            return super.add(paramObject);
+        }
+        ProxyCollections.beforeAdd(this, paramObject);
+        boolean bool = super.add(paramObject);
+        return ProxyCollections.afterAdd(this, paramObject, bool);
+    }
+
+    @Override
+    public void clear() {
+        if (!_directAccess) {
+            if (isDelayLoad()) {
+                load();
+            }
+            ProxyCollections.beforeClear(this);
+        }
+        super.clear();
+    }
+
+    @Override
+    public Iterator iterator() {
+        if (_directAccess) {
+            return super.iterator();
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        Iterator localIterator = super.iterator();
+        return ProxyCollections.afterIterator(this, localIterator);
+    }
+
+    @Override
+    public boolean remove(Object paramObject) {
+        if (_directAccess) {
+            return super.remove(paramObject);
+        }
+        ProxyCollections.beforeRemove(this, paramObject);
+        setDirectAccess(true);
+        boolean bool = super.remove(paramObject);
+        setDirectAccess(false);
+        return ProxyCollections.afterRemove(this, paramObject, bool);
+    }
+
+    @Override
+    public boolean removeAll(Collection paramCollection) {
+        if (_directAccess) {
+            return super.removeAll(paramCollection);
+        }
+        return ProxyCollections.removeAll(this, paramCollection);
+    }
+
+    @Override
+    public boolean addAll(Collection paramCollection) {
+        if (_directAccess) {
+            return super.addAll(paramCollection);
+        }
+        return ProxyCollections.addAll(this, paramCollection);
+    }
+
+    @Override
+    public boolean retainAll(Collection paramCollection) {
+        if (_directAccess) {
+            return super.retainAll(paramCollection);
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        return ProxyCollections.retainAll(this, paramCollection);
+    }
+
+    protected Object writeReplace() throws ObjectStreamException {
+        if (isDelayLoad()) {
+            load();
+        }
+        return Proxies.writeReplace(this, true);
+    }
+
+    @Override
+    public int size() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.isEmpty();
+    }
+
+    @Override
+    public boolean contains(Object o) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.contains(o);
+    }
+
+    @Override
+    public Object[] toArray() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.toArray();
+    }
+
+    @Override
+    public Object[] toArray(Object[] a) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.toArray(a);
+    }
+
+    @Override
+    public boolean containsAll(Collection c) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.containsAll(c);
+    }
+
+    @Override
+    public String toString() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.toString();
+    }
+
+    public boolean equals(Object paramObject) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.equals(paramObject);
+    }
+
+    public int hashCode() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.hashCode();
+    }
+
+    // //////////////////////////////////////
+    // DelayedProxy methods
+    // //////////////////////////////////////
+    public int getDelayedField() {
+        if (field == -1 || _detached) {
+            return _delayedField;
+        }
+        return field;
+    }
+
+    public OpenJPAStateManager getDelayedOwner() {
+        if (sm == null || _detached) {
+            return _delayedSm;
+        }
+        return sm;
+    }
+
+    public boolean isDirectAccess() {
+        return _directAccess;
+    }
+
+    public void setDirectAccess(boolean direct) {
+        _directAccess = direct;
+    }
+
+    public BrokerFactory getBrokerFactory() {
+        return _brokerFactory;
+    }
+
+    @Override
+    public void load() {
+        ProxyCollections.loadCollection(this);
+    }
+
+    @Override
+    public Broker getBroker() {
+        if (_broker == null || _broker.isClosed()) {
+            if (_brokerFactory != null) {
+                _broker = _brokerFactory.newBroker();
+            }
+        }
+        return _broker;
+    }
+
+    @Override
+    public void closeBroker() {
+        if (_broker != null && !_broker.isClosed()) {
+            _broker.setAutoDetach(AutoDetach.DETACH_CLOSE);
+            _broker.close();
+            _broker = null;
+        }
+    }
+
+    @Override
+    public OpenJPAStateManager getOwnerStateManager() {
+        return _ownerSm;
+    }
+
+    @Override
+    public boolean isDetached() {
+        return _detached;
+    }
+
+    public boolean isDelayLoad() {
+        return ProxyCollections.isDelayed(this);
+    }
+}
+

Propchange: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedHashSetProxy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedLinkedHashSetProxy.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedLinkedHashSetProxy.java?rev=1335720&view=auto
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedLinkedHashSetProxy.java (added)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedLinkedHashSetProxy.java Tue May  8 19:46:20 2012
@@ -0,0 +1,361 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.util;
+
+import java.io.ObjectStreamException;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+
+import org.apache.openjpa.kernel.AutoDetach;
+import org.apache.openjpa.kernel.Broker;
+import org.apache.openjpa.kernel.BrokerFactory;
+import org.apache.openjpa.kernel.DetachedStateManager;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+
+/**
+ * LinkedHashSet proxy with delay loading capability.  Allows non-indexed
+ * add and remove operations to occur on an unloaded collection.  Operations
+ * that require a load will trigger a load.
+ */
+@SuppressWarnings({"rawtypes","unchecked"})
+public class DelayedLinkedHashSetProxy extends LinkedHashSet implements DelayedProxy, ProxyCollection {
+    private transient OpenJPAStateManager sm;
+    private transient int field;
+    private transient CollectionChangeTracker changeTracker;
+    private transient Class<?> elementType;
+
+    private transient OpenJPAStateManager _ownerSm;
+    private transient boolean _directAccess = false;
+    private transient BrokerFactory _brokerFactory = null;
+    private transient Broker _broker = null;
+    private transient OpenJPAStateManager _delayedSm;
+    private transient int _delayedField;
+    private transient boolean _detached = false;
+
+    public DelayedLinkedHashSetProxy(Collection<?> paramCollection) {
+        super(paramCollection);
+    }
+
+    public DelayedLinkedHashSetProxy(int paramInt, float paramFloat) {
+        super(paramInt, paramFloat);
+    }
+
+    public DelayedLinkedHashSetProxy(int paramInt) {
+        super(paramInt);
+    }
+
+    public DelayedLinkedHashSetProxy() {
+    }
+
+    public void setOwner(OpenJPAStateManager paramOpenJPAStateManager,
+            int paramInt) {
+        // If clearing the owner of this proxy, store away what is necessary for
+        // delayed loading
+        if (sm != null && detaching(paramOpenJPAStateManager, paramInt)) {
+            _detached = true;
+            _delayedSm = sm;
+            _delayedField = field;
+        } else {
+            _detached = false;
+        }
+
+        this.sm = paramOpenJPAStateManager;
+        if (sm != null && sm.getPersistenceCapable() != null) {
+            _ownerSm = (OpenJPAStateManager) sm.getPersistenceCapable()
+                    .pcGetStateManager();
+        }
+        this.field = paramInt;
+        if (sm != null && sm.getContext() != null) {
+            _brokerFactory = sm.getContext().getBroker().getBrokerFactory();
+        }
+    }
+
+    private boolean detaching(OpenJPAStateManager paramOpenJPAStateManager,
+            int paramInt) {
+        if ((paramOpenJPAStateManager == null && paramInt == -1)
+                || (paramOpenJPAStateManager != null && paramOpenJPAStateManager instanceof DetachedStateManager)) {
+            return true;
+        }
+        return false;
+    }
+
+    public OpenJPAStateManager getOwner() {
+        return this.sm;
+    }
+
+    public int getOwnerField() {
+        return this.field;
+    }
+
+    public ChangeTracker getChangeTracker() {
+        return this.changeTracker;
+    }
+
+    @Override
+    public Object copy(Object paramObject) {
+        return new LinkedHashSet((Collection) paramObject);
+    }
+
+    public Class getElementType() {
+        return this.elementType;
+    }
+
+    public ProxyCollection newInstance(Class paramClass,
+            Comparator paramComparator, boolean paramBoolean1,
+            boolean paramBoolean2) {
+        DelayedLinkedHashSetProxy localproxy = new DelayedLinkedHashSetProxy();
+        localproxy.elementType = paramClass;
+        if (paramBoolean1)
+            localproxy.changeTracker = new DelayedCollectionChangeTrackerImpl(
+                    localproxy, false, false, paramBoolean2);
+        return localproxy;
+    }
+
+    @Override
+    public Object clone() {
+        if (isDirectAccess()) {
+            return super.clone();
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        Proxy localProxy = (Proxy) super.clone();
+        localProxy.setOwner(null, 0);
+        return localProxy;
+    }
+
+    @Override
+    public boolean add(Object paramObject) {
+        if (_directAccess) {
+            return super.add(paramObject);
+        }
+        ProxyCollections.beforeAdd(this, paramObject);
+        boolean bool = super.add(paramObject);
+        return ProxyCollections.afterAdd(this, paramObject, bool);
+    }
+
+    @Override
+    public void clear() {
+        if (!_directAccess) {
+            if (isDelayLoad()) {
+                load();
+            }
+            ProxyCollections.beforeClear(this);
+        }
+        super.clear();
+    }
+
+    @Override
+    public Iterator iterator() {
+        if (_directAccess) {
+            return super.iterator();
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        Iterator localIterator = super.iterator();
+        return ProxyCollections.afterIterator(this, localIterator);
+    }
+
+    @Override
+    public boolean remove(Object paramObject) {
+        if (_directAccess) {
+            return super.remove(paramObject);
+        }
+        ProxyCollections.beforeRemove(this, paramObject);
+        setDirectAccess(true);
+        boolean bool = super.remove(paramObject);
+        setDirectAccess(false);
+        return ProxyCollections.afterRemove(this, paramObject, bool);
+    }
+
+    @Override
+    public boolean removeAll(Collection paramCollection) {
+        if (_directAccess) {
+            return super.removeAll(paramCollection);
+        }
+        return ProxyCollections.removeAll(this, paramCollection);
+    }
+
+    @Override
+    public boolean addAll(Collection paramCollection) {
+        if (_directAccess) {
+            return super.addAll(paramCollection);
+        }
+        return ProxyCollections.addAll(this, paramCollection);
+    }
+
+    @Override
+    public boolean retainAll(Collection paramCollection) {
+        if (_directAccess) {
+            return super.retainAll(paramCollection);
+        }
+        if (isDelayLoad()) {
+            load();
+        }
+        return ProxyCollections.retainAll(this, paramCollection);
+    }
+
+    protected Object writeReplace() throws ObjectStreamException {
+        if (isDelayLoad()) {
+            load();
+        }
+        return Proxies.writeReplace(this, true);
+    }
+
+    @Override
+    public int size() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.isEmpty();
+    }
+
+    @Override
+    public boolean contains(Object o) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.contains(o);
+    }
+
+    @Override
+    public Object[] toArray() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.toArray();
+    }
+
+    @Override
+    public Object[] toArray(Object[] a) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.toArray(a);
+    }
+
+    @Override
+    public boolean containsAll(Collection c) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.containsAll(c);
+    }
+
+    @Override
+    public String toString() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.toString();
+    }
+
+    public boolean equals(Object paramObject) {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.equals(paramObject);
+    }
+
+    public int hashCode() {
+        if (!_directAccess && isDelayLoad()) {
+            load();
+        }
+        return super.hashCode();
+    }
+
+    // //////////////////////////////////////
+    // DelayedProxy methods
+    // //////////////////////////////////////
+    public int getDelayedField() {
+        if (field == -1 || _detached) {
+            return _delayedField;
+        }
+        return field;
+    }
+
+    public OpenJPAStateManager getDelayedOwner() {
+        if (sm == null || _detached) {
+            return _delayedSm;
+        }
+        return sm;
+    }
+
+    public boolean isDirectAccess() {
+        return _directAccess;
+    }
+
+    public void setDirectAccess(boolean direct) {
+        _directAccess = direct;
+    }
+
+    public BrokerFactory getBrokerFactory() {
+        return _brokerFactory;
+    }
+
+    @Override
+    public void load() {
+        ProxyCollections.loadCollection(this);
+    }
+
+    @Override
+    public Broker getBroker() {
+        if (_broker == null || _broker.isClosed()) {
+            if (_brokerFactory != null) {
+                _broker = _brokerFactory.newBroker();
+            }
+        }
+        return _broker;
+    }
+
+    @Override
+    public void closeBroker() {
+        if (_broker != null && !_broker.isClosed()) {
+            _broker.setAutoDetach(AutoDetach.DETACH_CLOSE);
+            _broker.close();
+            _broker = null;
+        }
+    }
+
+    @Override
+    public OpenJPAStateManager getOwnerStateManager() {
+        return _ownerSm;
+    }
+
+    @Override
+    public boolean isDetached() {
+        return _detached;
+    }
+
+    protected boolean isDelayLoad() {
+        return ProxyCollections.isDelayed(this);
+    }
+}

Propchange: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/util/DelayedLinkedHashSetProxy.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message