diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
index 3e047a87f..4f646c21b 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
@@ -441,10 +441,7 @@ public class JDBCStoreManager
public boolean load(OpenJPAStateManager sm, BitSet fields,
FetchState fetchState, int lockLevel, Object context) {
- JDBCFetchState jfetchState = (fetchState == null) ? (JDBCFetchState) getFetchConfiguration()
- .newFetchState()
- : (JDBCFetchState) fetchState;
-
+ JDBCFetchState jfetchState = (JDBCFetchState) fetchState;
JDBCFetchConfiguration jfetch = getFetchConfiguration(jfetchState);
// get a connection, or reuse current one
@@ -492,9 +489,10 @@ public class JDBCStoreManager
// now allow the fields to load themselves individually too
for (int i = 0, len = fields.length(); i < len; i++)
- if (fields.get(i) && !sm.getLoaded().get(i))
- mapping.getFieldMapping(i).load(sm, this, jfetchState);
-
+ if (fields.get(i) && !sm.getLoaded().get(i)) {
+ FieldMapping fm = mapping.getFieldMapping(i);
+ fm.load(sm, this, (JDBCFetchState)jfetchState.traverse(fm));
+ }
mapping.getVersion().afterLoad(sm, this);
return true;
} catch (ClassNotFoundException cnfe) {
@@ -514,8 +512,8 @@ public class JDBCStoreManager
}
public Collection loadAll(Collection sms, PCState state, int load,
- FetchState fetchState, Object context) {
- return ImplHelper.loadAll(sms, this, state, load, fetchState, context);
+ FetchConfiguration fetch, Object context) {
+ return ImplHelper.loadAll(sms, this, state, load, fetch, context);
}
public void beforeStateChange(OpenJPAStateManager sm, PCState fromState,
@@ -829,23 +827,25 @@ public class JDBCStoreManager
for (int i = 0; i < fms.length; i++) {
if (fms[i].isPrimaryKey() || sm.getLoaded().get(fms[i].getIndex()))
continue;
-
+
// check for eager result, and if not present do standard load
eres = res.getEager(fms[i]);
res.startDataRequest(fms[i]);
try {
- if (eres == res) {
+ if (eres == res) {
if (eagerToMany == null && fms[i].isEagerSelectToMany())
eagerToMany = fms[i];
else
- fms[i].loadEagerJoin(sm, this, fetchState, res);
+ fms[i].loadEagerJoin(sm, this,
+ (JDBCFetchState)fetchState.traverse(fms[i]), res);
} else if (eres != null) {
- processed = fms[i].loadEagerParallel(sm, this, fetchState,
- eres);
+ processed = fms[i].loadEagerParallel(sm, this,
+ (JDBCFetchState)fetchState.traverse(fms[i]), eres);
if (processed != eres)
res.putEager(fms[i], processed);
} else
- fms[i].load(sm, this, fetchState, res);
+ fms[i].load(sm, this,
+ (JDBCFetchState)fetchState.traverse(fms[i]), res);
} finally {
res.endDataRequest();
}
@@ -931,11 +931,11 @@ public class JDBCStoreManager
int jtype;
int mode;
for (int i = 0; i < fms.length; i++) {
- if (!requiresSelect(fms[i], sm, fields, fetchState))
- continue;
mode = fms[i].getEagerFetchMode();
if (mode == fetch.EAGER_NONE)
continue;
+ if (!requiresSelect(fms[i], sm, fields, fetchState))
+ continue;
// try to select with join first
jtype = (fms[i].getNullValue() == fms[i].NULL_EXCEPTION) ? sel.EAGER_INNER
@@ -985,7 +985,7 @@ public class JDBCStoreManager
if (sm != null && sm.getPCState() != PCState.TRANSIENT
&& sm.getLoaded().get(fm.getIndex()))
return false;
- return fetchState.requiresSelect(fm, true);
+ return fetchState.requiresFetch(fm);
}
/**
@@ -1059,17 +1059,19 @@ public class JDBCStoreManager
esel = sel.getEager(fms[i]);
if (esel != null) {
if (esel == sel)
- fms[i].selectEagerJoin(sel, sm, this, fetchState, eager);
+ fms[i].selectEagerJoin(sel, sm, this,
+ (JDBCFetchState)fetchState.traverse(fms[i]), eager);
else
- fms[i].selectEagerParallel(esel, sm, this, fetchState,
- eager);
+ fms[i].selectEagerParallel(esel, sm, this,
+ (JDBCFetchState)fetchState.traverse(fms[i]), eager);
seld = Math.max(0, seld);
} else if (requiresSelect(fms[i], sm, fields, fetchState)) {
- fseld = fms[i].select(sel, sm, this, fetchState, eager);
+ fseld = fms[i].select(sel, sm, this,
+ (JDBCFetchState)fetchState.traverse(fms[i]), eager);
seld = Math.max(fseld, seld);
} else if (optSelect(fms[i], sel, sm, fetchState)) {
- fseld = fms[i].select(sel, sm, this, fetchState,
- fetch.EAGER_NONE);
+ fseld = fms[i].select(sel, sm, this,
+ (JDBCFetchState)fetchState.traverse(fms[i]), fetch.EAGER_NONE);
// don't upgrade seld to > 0 based on these fields, since
// they're not in the calculated field set
@@ -1100,7 +1102,7 @@ public class JDBCStoreManager
.getLoaded().get(fm.getIndex()))
&& fm.supportsSelect(sel, sel.TYPE_TWO_PART, sm, this,
getFetchConfiguration(fetchState)) > 0
- && fetchState.requiresSelect(fm, true);
+ && fetchState.requiresFetch(fm);
}
/**
@@ -1141,12 +1143,15 @@ public class JDBCStoreManager
fms = subMappings[i].getDefinedFieldMappings();
for (int j = 0; j < fms.length; j++) {
// make sure in one of configured fetch groups
- if (!fms[j].isInDefaultFetchGroup()
- && !fetch.hasFetchGroup(fms[j].getFetchGroups())
- && !fetch.hasField(fms[j].getFullName())
- && (fms[j].isDefaultFetchGroupExplicit() || fms[j]
- .supportsSelect(sel, sel.TYPE_TWO_PART, sm, this, fetch) <= 0))
- continue;
+ if (fetchState.requiresFetch(fms[j])
+ || fms[j].supportsSelect(sel, sel.TYPE_TWO_PART, sm, this, fetch) <= 0)
+ continue;
+// if (!fms[j].isInDefaultFetchGroup()
+// && !fetch.hasAnyFetchGroup(fms[j].getFetchGroups())
+// && !fetch.hasField(fms[j].getFullName())
+// && (fms[j].isDefaultFetchGroupExplicit() || fms[j]
+// .supportsSelect(sel, sel.TYPE_TWO_PART, sm, this, fetch) <= 0))
+// continue;
// if we can join to the subclass, do so; much better chance
// that the field will be able to select itself without joins
@@ -1159,9 +1164,10 @@ public class JDBCStoreManager
// if can select with tables already selected, do it
if (fms[j].supportsSelect(sel, sel.TYPE_JOINLESS, sm, this,
- fetch) > 0)
- fms[j]
- .select(sel, null, this, fetchState, fetch.EAGER_NONE);
+ fetch) > 0 && fetchState.requiresFetch(fms[j]))
+ fms[j].select(sel, null, this,
+ (JDBCFetchState)fetchState.traverse(fms[j]),
+ fetch.EAGER_NONE);
}
}
}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java
index bf566331d..a63eaee3f 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java
@@ -92,7 +92,7 @@ public class PagingResultObjectProvider
BitSet paged = null;
for (int i = 0; i < fms.length; i++) {
if (fetchState != null
- && !fetchState.requiresSelect(fms[i], false))
+ && !fetchState.requiresFetch(fms[i]))
continue;
if (fms[i].supportsSelect(sel, sel.EAGER_PARALLEL, null, store,
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/abstractstore/AbstractStoreManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/abstractstore/AbstractStoreManager.java
index 17e981aa5..a2a369766 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/abstractstore/AbstractStoreManager.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/abstractstore/AbstractStoreManager.java
@@ -233,8 +233,8 @@ public abstract class AbstractStoreManager
* advantageous.
*/
public Collection loadAll(Collection sms, PCState state, int load,
- FetchState fetchState, Object context) {
- return ImplHelper.loadAll(sms, this, state, load, fetchState, context);
+ FetchConfiguration fetch, Object context) {
+ return ImplHelper.loadAll(sms, this, state, load, fetch, context);
}
/**
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
index 9ca86f311..170951fb8 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
@@ -408,12 +408,9 @@ public class DataCacheStoreManager
}
public Collection loadAll(Collection sms, PCState state, int load,
- FetchState fetchState, Object edata) {
- FetchConfiguration fetch = (fetchState == null)
- ? _ctx.getFetchConfiguration()
- : fetchState.getFetchConfiguration();
+ FetchConfiguration fetch, Object edata) {
if (isLocking(fetch))
- return super.loadAll(sms, state, load, fetchState, edata);
+ return super.loadAll(sms, state, load, fetch, edata);
Map unloaded = null;
OpenJPAStateManager sm;
@@ -435,7 +432,7 @@ public class DataCacheStoreManager
//### the 'data.type' access here probably needs
//### to be addressed for bug 511
sm.initialize(data.getType(), state);
- data.load(sm, fetchState, edata);
+ data.load(sm, fetch.newFetchState(), edata);
} else
unloaded = addUnloaded(sm, null, unloaded);
} else if (load != FORCE_LOAD_NONE
@@ -443,6 +440,7 @@ public class DataCacheStoreManager
data = cache.get(sm.getObjectId());
if (data != null) {
// load unloaded fields
+ FetchState fetchState = fetch.newFetchState();
fields = sm.getUnloaded(fetchState);
data.load(sm, fields, fetchState, edata);
if (fields.length() > 0)
@@ -458,7 +456,7 @@ public class DataCacheStoreManager
// load with delegate
Collection failed = super.loadAll(unloaded.keySet(), state, load,
- fetchState, edata);
+ fetch, edata);
if (!_ctx.getPopulateDataCache())
return failed;
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java
index 8321bab8e..ed3d93e7c 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java
@@ -575,7 +575,7 @@ public class PCDataGenerator
code.invokevirtual().setMethod(FieldMetaData.class,
"getFetchGroups", Set.class, null);
code.invokeinterface().setMethod
- (FetchConfiguration.class, "hasFetchGroup",
+ (FetchConfiguration.class, "hasAnyFetchGroup",
boolean.class, new Class[]{ Set.class });
JumpInstruction ifins = code.ifne();
code.aload().setLocal(fetch);
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
index 4b589a56e..f6ff06547 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
@@ -694,11 +694,13 @@ public class BrokerImpl
int flags = OID_COPY | OID_ALLOW_NEW | OID_NODELETED;
if (!validate)
flags |= OID_NOVALIDATE;
- return find(oid, null, null, null, flags, call);
+ return find(oid, _fc.newFetchState (), null, null, flags, call);
}
public Object find(Object oid, FetchState fetchState, BitSet exclude,
Object edata, int flags) {
+ if (fetchState == null)
+ fetchState = _fc.newFetchState ();
return find(oid, fetchState, exclude, edata, flags, null);
}
@@ -717,8 +719,6 @@ public class BrokerImpl
}
beginOperation(true);
- if (fetchState == null)
- fetchState = _fc.newFetchState();
try {
assertNontransactionalRead();
@@ -842,18 +842,18 @@ public class BrokerImpl
int flags = OID_COPY | OID_ALLOW_NEW | OID_NODELETED;
if (!validate)
flags |= OID_NOVALIDATE;
- return findAll(oids, null, null, null, flags, call);
+ return findAll(oids, _fc, null, null, flags, call);
}
- public Object[] findAll(Collection oids, FetchState fetchState,
+ public Object[] findAll(Collection oids, FetchConfiguration fetch,
BitSet exclude, Object edata, int flags) {
- return findAll(oids, fetchState, exclude, edata, flags, null);
+ return findAll(oids, fetch, exclude, edata, flags, null);
}
/**
* Internal finder.
*/
- protected Object[] findAll(Collection oids, FetchState fetchState,
+ protected Object[] findAll(Collection oids, FetchConfiguration fetch,
BitSet exclude, Object edata, int flags, FindCallbacks call) {
// throw any exceptions for null oids up immediately
if (oids == null)
@@ -867,9 +867,6 @@ public class BrokerImpl
_loading = new HashMap((int) (oids.size() * 1.33 + 1));
if (call == null)
call = this;
- if (fetchState == null)
- fetchState = _fc.newFetchState();
- FetchConfiguration fetch = fetchState.getFetchConfiguration();
beginOperation(true);
try {
assertNontransactionalRead();
@@ -915,7 +912,7 @@ public class BrokerImpl
PCState state = (transState) ? PCState.PCLEAN
: PCState.PNONTRANS;
Collection failed = _store.loadAll(load, state,
- StoreManager.FORCE_LOAD_NONE, fetchState, edata);
+ StoreManager.FORCE_LOAD_NONE, _fc, edata);
// set failed instances to null
if (failed != null && !failed.isEmpty()) {
@@ -937,8 +934,8 @@ public class BrokerImpl
sm = (StateManagerImpl) _loading.get(oid);
if (sm != null && requiresLoad(sm, true, edata, flags)) {
try {
- sm.load(fetchState, StateManagerImpl.LOAD_FGS, exclude,
- edata, false);
+ sm.load(fetch.newFetchState(), StateManagerImpl.LOAD_FGS,
+ exclude, edata, false);
if (active) {
_lm.lock(sm, level, fetch.getLockTimeout(), edata);
sm.readLocked(level, fetch.getWriteLockLevel());
@@ -2687,7 +2684,7 @@ public class BrokerImpl
// refresh all
if (load != null) {
Collection failed = _store.loadAll(load, null,
- _store.FORCE_LOAD_REFRESH, _fc.newFetchState(), null);
+ _store.FORCE_LOAD_REFRESH, _fc, null);
if (failed != null && !failed.isEmpty())
exceps = add(exceps, newObjectNotFoundException(failed));
@@ -2812,8 +2809,7 @@ public class BrokerImpl
if (load != null) {
int mode = (dfgOnly) ? _store.FORCE_LOAD_DFG
: _store.FORCE_LOAD_ALL;
- failed = _store.loadAll(load, null, mode, _fc.newFetchState(),
- null);
+ failed = _store.loadAll(load, null, mode, _fc, null);
if (failed != null && !failed.isEmpty())
exceps = add(exceps, newObjectNotFoundException(failed));
}
@@ -3196,7 +3192,7 @@ public class BrokerImpl
Collection failed = null;
if (load != null) {
failed = _store.loadAll(load, null, _store.FORCE_LOAD_NONE,
- _fc.newFetchState(), null);
+ _fc, null);
if (failed != null && !failed.isEmpty())
exceps = add(exceps,
newObjectNotFoundException(failed));
@@ -4087,7 +4083,7 @@ public class BrokerImpl
Object oid = ApplicationIds.create(pc, meta);
if (oid == null)
return false;
- return find(oid, _fc.newFetchState(), EXCLUDE_ALL, null, 0) != null;
+ return find(oid, null, EXCLUDE_ALL, null, 0) != null;
}
public OpenJPAStateManager getStateManager(Object obj) {
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
index 741d187d3..7e04d5d58 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
@@ -198,10 +198,10 @@ public class DelegatingBroker
}
}
- public Object[] findAll(Collection oids, FetchState fetchState,
+ public Object[] findAll(Collection oids, FetchConfiguration fetch,
BitSet exclude, Object edata, int flags) {
try {
- return _broker.findAll(oids, fetchState, exclude, edata, flags);
+ return _broker.findAll(oids, fetch, exclude, edata, flags);
} catch (RuntimeException re) {
throw translate(re);
}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java
index 392d9fa3f..b9c6ad7a6 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java
@@ -229,9 +229,9 @@ public class DelegatingFetchConfiguration
}
}
- public boolean hasFetchGroup(Set groups) {
+ public boolean hasAnyFetchGroup(Set groups) {
try {
- return _fetch.hasFetchGroup(groups);
+ return _fetch.hasAnyFetchGroup(groups);
} catch (RuntimeException re) {
throw translate(re);
}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
index 41e37ec39..43a672f26 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
@@ -114,8 +114,8 @@ public abstract class DelegatingStoreManager
}
public Collection loadAll(Collection sms, PCState state, int load,
- FetchState fetchState, Object context) {
- return _store.loadAll(sms, state, load, fetchState, context);
+ FetchConfiguration fetch, Object context) {
+ return _store.loadAll(sms, state, load, fetch, context);
}
public void beforeStateChange(OpenJPAStateManager sm, PCState fromState,
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
index b6a35b921..0e71c66e4 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
@@ -223,7 +223,7 @@ public class DetachManager
FieldMetaData[] fmds = sm.getMetaData().getFields();
for (int i = 0; i < fmds.length; i++) {
if (fmds[i].isPrimaryKey() || fmds[i].isInDefaultFetchGroup()
- || fetch.hasFetchGroup(fmds[i].getFetchGroups())
+ || fetch.hasAnyFetchGroup(fmds[i].getFetchGroups())
|| fetch.hasField(fmds[i].getFullName()))
idxs.set(i);
}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
index fe62450c9..3a73d1e22 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
@@ -136,9 +136,10 @@ public class DetachedStateManager
load.set(i);
}
}
-
- sm.loadFields(load, null, broker.getFetchConfiguration().
- getWriteLockLevel(), null, true);
+ FetchConfiguration fc = broker.getFetchConfiguration();
+ FetchState fetchState = fc.newFetchState();
+ sm.loadFields(load, fetchState, fc.getWriteLockLevel(), null, true);
+
}
sm.setVersion(_version);
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java
index 11a189089..e925ae316 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java
@@ -45,6 +45,7 @@ public interface FetchConfiguration
public static final String FETCH_GROUP_ALL =
"org.apache.openjpa.kernel.FetchConfiguration.FETCH_GROUP_ALL";
+ public static final String FETCH_GROUP_DEFAULT = "default";
/**
* Return the context assiciated with this configuration;
* may be null if it has not been set or this object has been serialized.
@@ -144,7 +145,7 @@ public interface FetchConfiguration
*
* @since 4.1
*/
- public boolean hasFetchGroup(Set groups);
+ public boolean hasAnyFetchGroup(Set groups);
/**
* Adds group
to the set of fetch group names to
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java
index cf5ca3e69..03f4c1909 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java
@@ -108,6 +108,7 @@ public class FetchConfigurationImpl
public void copy(FetchConfiguration fetch) {
setFetchBatchSize(fetch.getFetchBatchSize());
+ setMaxFetchDepth(fetch.getMaxFetchDepth());
setQueryCache(fetch.getQueryCache());
setFlushBeforeQueries(fetch.getFlushBeforeQueries());
setLockTimeout(fetch.getLockTimeout());
@@ -172,11 +173,11 @@ public class FetchConfigurationImpl
public synchronized boolean hasFetchGroup(String group) {
return _fetchGroups != null
- && ((group != null && _fetchGroups.contains(group))
+ && (_fetchGroups.contains(group)
|| _fetchGroups.contains(FETCH_GROUP_ALL));
}
- public synchronized boolean hasFetchGroup(Set groups) {
+ public synchronized boolean hasAnyFetchGroup(Set groups) {
if (_fetchGroups != null && groups != null) {
Iterator iter = groups.iterator();
while (iter.hasNext()) {
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchState.java
index 62e7c805e..57a1c3c93 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchState.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchState.java
@@ -1,68 +1,135 @@
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed 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.kernel;
-
-import org.apache.openjpa.meta.FieldMetaData;
-
-/**
- * Defines the decision to include fields for selection or loading during
- * a fetch operation.
- *
- * @author root
+ * state.
+ *
+ * @author 0)
context.saveFields(true);
context.clearFields();
- context.load(context.getBroker().getFetchConfiguration().
- newFetchState(), context.LOAD_FGS, null, null, true);
+ context.load(null, context.LOAD_FGS, null, null, true);
}
return PDIRTY;
}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
index f2dab9791..c15023eb8 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
@@ -18,14 +18,7 @@ package org.apache.openjpa.kernel;
import java.io.IOException;
import java.io.ObjectOutput;
import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Calendar;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.TimeZone;
+import java.util.*;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.conf.OpenJPAConfiguration;
@@ -325,6 +318,8 @@ public class StateManagerImpl
if (!forWrite && (!isPersistent() || isNew() || isDeleted()))
return false;
+ if (fetchState==null)
+ fetchState = _broker.getFetchConfiguration().newFetchState();
// if any fields being loaded, do state transitions for read
BitSet fields = getUnloadedInternal(fetchState, loadMode, exclude);
boolean active = _broker.isActive();
@@ -2760,9 +2755,9 @@ public class StateManagerImpl
protected void loadField(int field, int lockLevel, boolean forWrite,
boolean fgs) {
- loadField(field, _broker.getFetchConfiguration().newFetchState(),
- lockLevel, forWrite, fgs);
- }
+ FetchConfiguration fc = _broker.getFetchConfiguration();
+ loadField(field, fc.newFetchState(),lockLevel, forWrite, fgs);
+ }
/**
* Load the given field's fetch group; the field itself may already be
@@ -2799,7 +2794,7 @@ public class StateManagerImpl
// call this method even if there are no unloaded fields; loadFields
// takes care of things like loading version info and setting PC
// flags
- loadFields(fields, null, lockLevel, null, forWrite);
+ loadFields(fields, fetchState, lockLevel, null, forWrite);
}
/**
@@ -2869,15 +2864,12 @@ public class StateManagerImpl
// is this field in the dfg?
FieldMetaData[] fmds = _meta.getDefaultFetchGroupFields();
- if (fmds.length > 0 && field != -1
- && !requiredByDefault(_meta.getField(field), fetchState))
- return;
- // see if the dfg is fully loaded
+ // see if any fetch group with postLoad=true is fully loaded
boolean isLoaded = true;
for (int i = 0; isLoaded && i < fmds.length; i++)
if (!_loaded.get(fmds[i].getIndex())
- && requiredByDefault(fmds[i], fetchState))
+ && requiresPostLoadCallabck(fmds[i], fetchState))
isLoaded = false;
if (isLoaded) {
_flags |= FLAG_DFG;
@@ -2885,15 +2877,18 @@ public class StateManagerImpl
}
}
- private boolean requiredByDefault(FieldMetaData fm, FetchState fetchState) {
+ private boolean requiresPostLoadCallabck(FieldMetaData fm, FetchState fetchState) {
if (fm == null)
return false;
- if (fetchState == null)
- return fm.isInDefaultFetchGroup()
- && _broker.getFetchConfiguration().hasFetchGroup
- (FetchGroup.getDefaultGroupName());
- else
- return fetchState.isDefault(fm);
+ Set fetchGroups = fm.getFetchGroups();
+ for (Iterator i = fetchGroups.iterator(); i.hasNext();)
+ {
+ String fg = i.next().toString();
+ if (_broker.getFetchConfiguration().hasFetchGroup(fg)
+ && fm.getDeclaringMetaData().getFetchGroup(fg).isPostLoad())
+ return true;
+ }
+ return false;
}
/**
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
index 1f56d3e5f..86772af7f 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
@@ -143,7 +143,7 @@ public interface StoreContext {
*
* @see #find(Object,FetchState,BitSet,Object,int)
*/
- public Object[] findAll(Collection oids, FetchState fetchState,
+ public Object[] findAll(Collection oids, FetchConfiguration fetch,
BitSet exclude, Object edata, int flags);
/**
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
index f701d6b0e..c1e9f9609 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
@@ -210,7 +210,7 @@ public interface StoreManager
* @see org.apache.openjpa.util.ImplHelper#loadAll
*/
public Collection loadAll(Collection sms, PCState state, int load,
- FetchState fetchState, Object edata);
+ FetchConfiguration fetch, Object edata);
/**
* Notification that the given state manager is about to change its
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java
index 7320eccd3..fbbcd41ab 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java
@@ -130,7 +130,7 @@ class VersionAttachStrategy
break;
case DETACH_FGS:
if (fmds[i].isInDefaultFetchGroup()
- || fetch.hasFetchGroup(fmds[i].getFetchGroups())
+ || fetch.hasAnyFetchGroup(fmds[i].getFetchGroups())
|| fetch.hasField(fmds[i].getFullName()))
attachField(manager, toAttach, sm, fmds[i], true);
break;
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
index 8108c8778..35b09199a 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
@@ -1922,10 +1922,12 @@ public class ClassMetaData
* the same name.
*/
public synchronized FetchGroup addFetchGroup(String name) {
+ if (name == null || name.trim().length()==0)
+ throw new MetaDataException(_loc.get("empty-fg-name", this));
FetchGroup fg = (FetchGroup) _fgs.get(name);
if (fg == null) {
- fg = newFetchGroup(name);
- _fgs.put(name, fg);
+ fg = new FetchGroup(this, name);
+ _fgs.put(name, fg);
}
return fg;
@@ -1933,33 +1935,19 @@ public class ClassMetaData
/**
* Gets a named fecth group. If not available in this receiver then looks
- * up the inheritence hierarchy. Creates if it does not exist and
- * mustBe
is false.
+ * up the inheritence hierarchy.
*
* @param name name of a fetch group.
- * @param mustBe if true then the named group must exist in this receiver
- * or any of its persistent super classes.
- * @return an existing or newly created fecth group of the given name.
+ * @return an existing fecth group of the given name if known to this
+ * receiver or any of its superclasses. Otherwise null.
*/
- public synchronized FetchGroup getFetchGroup(String name, boolean mustBe) {
+ public synchronized FetchGroup getFetchGroup(String name) {
FetchGroup fg = (FetchGroup) _fgs.get(name);
if (fg == null) {
ClassMetaData scm = getPCSuperclassMetaData();
if (scm != null)
- fg = scm.getFetchGroup(name, false);
+ fg = scm.getFetchGroup(name);
}
-
- if (fg == null)
- if (mustBe)
- return null;
- else
- fg = addFetchGroup(name);
-
- return fg;
- }
-
- protected FetchGroup newFetchGroup(String name) {
- FetchGroup fg = new FetchGroup(this, name);
return fg;
}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java
index ca0ddb91b..c0a4fb31d 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FetchGroup.java
@@ -1,205 +1,173 @@
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed 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.meta;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.openjpa.lib.meta.SourceTracker;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.util.MetaDataException;
-
-/**
- * Captures fetch group metadata.
- */
-public class FetchGroup
- implements SourceTracker {
-
- private final String _name;
- private final ClassMetaData _declaringClass;
- private List _includes;
- private Map _depths;
-
- public static final int DEFAULT_RECURSION_DEPTH = 1;
- private static String DEFAULT_GROUP_NAME = "default";
-
- private static final Localizer _loc = Localizer.forPackage
- (FetchGroup.class);
-
- /**
- * Supply immutable name.
- *
- * @param name must not by null or empty.
- */
- FetchGroup(ClassMetaData cm, String name) {
- super();
-
- if (cm == null)
- throw new MetaDataException(_loc.get("null-class-fg", name));
- if (StringUtils.isEmpty(name))
- throw new MetaDataException(_loc.get("invalid-fg-name", cm,
- name));
-
- _name = name;
- _declaringClass = cm;
- }
-
- public String getName() {
- return _name;
- }
-
- /**
- * Includes given fetch group within this receiver.
- *
- * @param fg must not be null or this receiver itself or must not include
- * this receiver.
- */
- public void addInclude(FetchGroup fg) {
- if (fg == this)
- throw new MetaDataException(_loc.get("self-include-fg", this));
- if (fg == null)
- throw new MetaDataException(_loc.get("null-include-fg", this));
- if (fg.includes(this, true))
- throw new MetaDataException(_loc.get("cyclic-fg", this, fg));
-
- if (_includes == null)
- _includes = new ArrayList();
- _includes.add(fg);
- }
-
- /**
- * Affirms if given fetch group is included by this receiver.
- *
- * @param fg
- * @param recurse if true then recursively checks within the included
- * fecth groups. Otherwise just checks within direct includes.
- */
- public boolean includes(FetchGroup fg, boolean recurse) {
- if (_includes == null)
- return false;
- if (_includes.contains(fg))
- return true;
-
- if (recurse)
- for (Iterator i = _includes.iterator(); i.hasNext();)
- if (((FetchGroup) i.next()).includes(fg, true))
- return true;
-
- return false;
- }
-
- /**
- * Sets recursion depth for a field.
- *
- * @param fm
- * @param depth
- */
- public void setDepthFor(FieldMetaData fm, int depth) {
- if (depth < -1)
- throw new MetaDataException(_loc.get("invalid-fetch-depth",
- _name, fm, new Integer(depth)));
-
- if (_depths == null)
- _depths = new HashMap();
-
- _depths.put(fm, new Integer(depth));
- }
-
- /**
- * Gets recusrion depth for the given field.
- *
- * @param fm
- * @return defaults to 1.
- */
- public int getDepthFor(FieldMetaData fm) {
- if (_depths == null || !_depths.containsKey(fm))
- return DEFAULT_RECURSION_DEPTH;
-
- return ((Integer) _depths.get(fm)).intValue();
- }
-
- /**
- * Set the name for default group.
- * It is expected to be set only once by a compliant implementation.
- * If multiple attempts are made to set the default group name,
- * then an attempt will succeed only for the first time or if the given
- * name matches with the current name.
- *
- * @param name of the default fetch group
- */
- public static void setDefaultGroupName(String name) {
- //###JDO2 -- better mechanics required to set default group name
- DEFAULT_GROUP_NAME = name;
- }
-
- /**
- * Get the name in which default fetch group is known.
- *
- * @return name of the default group. Can be null, if not set.
- */
- public static final String getDefaultGroupName() {
- return DEFAULT_GROUP_NAME;
- }
-
- /**
- * Affirms equality if the other has the same name.
- */
- public boolean equals(Object other) {
- if (other instanceof FetchGroup) {
- FetchGroup that = (FetchGroup) other;
- return _name.equals(that._name)
- && _declaringClass.equals(that._declaringClass);
- }
-
- return false;
- }
-
- public int hashCode() {
- return _name.hashCode() + _declaringClass.hashCode();
- }
-
- public String toString() {
- return _name;
- }
-
- /////////////////
- // SourceTracker
- /////////////////
-
- public File getSourceFile() {
- return _declaringClass.getSourceFile();
- }
-
- public Object getSourceScope() {
- return _declaringClass;
- }
-
- public int getSourceType() {
- return _declaringClass.getSourceType();
- }
-
- public String getResourceName() {
- return _declaringClass.getResourceName ();
- }
-}
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * Licensed 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.meta;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.lib.meta.SourceTracker;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.UserException;
+
+/**
+ * Captures fetch group metadata.
+ */
+public class FetchGroup implements SourceTracker {
+
+ private final String _name;
+ private final ClassMetaData _declaringClass;
+ private List _includes;
+ private Map _depths;
+ private boolean _postLoad;
+ public static final int DEFAULT_RECURSION_DEPTH = 1;
+ private static final Localizer _loc =
+ Localizer.forPackage(FetchGroup.class);
+
+ /**
+ * Supply immutable name.
+ *
+ * @param must not by null or empty.
+ */
+ FetchGroup(ClassMetaData cm, String name) {
+ super();
+ if (StringUtils.isEmpty(name))
+ throw new UserException(_loc.get("invalid-fg-name", cm, name));
+ _name = name;
+ _declaringClass = cm;
+ }
+
+ public String getName() {
+ return _name;
+ }
+
+ /**
+ * Includes given fetch group within this receiver.
+ *
+ * @param fg must not be null or this receiver itself or must not include
+ * this receiver.
+ */
+ public void addInclude(FetchGroup fg) {
+ if (fg == this)
+ throw new UserException(_loc.get("self-include-fg", this));
+ if (fg == null)
+ throw new UserException(_loc.get("null-include-fg", this));
+ if (fg.includes(this, true))
+ throw new UserException(_loc.get("cyclic-fg", this, fg));
+ if (_includes == null)
+ _includes = new ArrayList();
+ _includes.add(fg);
+ }
+
+ /**
+ * Affirms if given fetch group is included by this receiver.
+ *
+ * @param fg
+ * @param recurse if true then recursively checks within the included
+ * fecth groups. Otherwise just checks within direct includes.
+ * @return
+ */
+ public boolean includes(FetchGroup fg, boolean recurse) {
+ if (_includes == null)
+ return false;
+ if (_includes.contains(fg))
+ return true;
+ if (recurse)
+ for (Iterator i = _includes.iterator(); i.hasNext();)
+ if (((FetchGroup) i.next()).includes(fg, true))
+ return true;
+ return false;
+ }
+
+ /**
+ * Sets recursion depth for a field.
+ *
+ * @param fm
+ * @param depth
+ */
+ public void setDepthFor(FieldMetaData fm, int depth) {
+ if (depth < -1)
+ throw new UserException(_loc.get("invalid-fetch-depth",
+ _name, fm, new Integer(depth)));
+ if (_depths == null)
+ _depths = new HashMap();
+ _depths.put(fm, new Integer(depth));
+ }
+
+ /**
+ * Gets recusrion depth for the given field.
+ *
+ * @param fm
+ * @return defaults to 1.
+ */
+ public int getDepthFor(FieldMetaData fm) {
+ if (_depths == null || !_depths.containsKey(fm))
+ return DEFAULT_RECURSION_DEPTH;
+ return ((Integer) _depths.get(fm)).intValue();
+ }
+
+
+ public boolean isPostLoad () {
+ return _postLoad;
+ }
+
+ public void setPostLoad (boolean flag) {
+ _postLoad = flag;
+ }
+
+ /**
+ * Affirms equality if the other has the same name.
+ */
+ public boolean equals(Object other) {
+ if (other instanceof FetchGroup) {
+ FetchGroup that = (FetchGroup) other;
+ return _name.equals(that._name)
+ && _declaringClass.equals(that._declaringClass);
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return _name.hashCode() + _declaringClass.hashCode();
+ }
+
+ public String toString() {
+ return _name;
+ }
+
+ /////////////////
+ // SourceTracker
+ /////////////////
+ public File getSourceFile() {
+ return _declaringClass.getSourceFile();
+ }
+
+ public Object getSourceScope() {
+ return _declaringClass;
+ }
+
+ public int getSourceType() {
+ return _declaringClass.getSourceType();
+ }
+
+ public String getResourceName() {
+ return _declaringClass.getResourceName();
+ }
+}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
index fb2c680bf..f3e58e962 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java
@@ -39,6 +39,7 @@ import org.apache.commons.collections.comparators.ComparatorChain;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.kernel.FetchConfiguration;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.StoreContext;
import org.apache.openjpa.lib.conf.Configurations;
@@ -849,13 +850,13 @@ public class FieldMetaData
*/
public void addFetchGroup(String fg) {
if (StringUtils.isEmpty(fg))
- return;
- if (getDeclaringMetaData().getFetchGroup(fg, false) == null)
+ throw new MetaDataException(_loc.get("bad-fg", fg));
+ if (getDeclaringMetaData().getFetchGroup(fg) == null)
throw new MetaDataException(_loc.get("unknown-fg", fg));
if (_fgs == null)
_fgs = new HashSet();
_fgs.add(fg);
- if (fg.equals(FetchGroup.getDefaultGroupName()))
+ if (fg.equals(FetchConfiguration.FETCH_GROUP_DEFAULT))
setInDefaultFetchGroup(true);
}
@@ -863,7 +864,7 @@ public class FieldMetaData
if (_fgs == null)
return;
_fgs.remove(fg);
- if (fg != null && fg.equals(FetchGroup.getDefaultGroupName()))
+ if (FetchConfiguration.FETCH_GROUP_DEFAULT.equals(fg))
setInDefaultFetchGroup(false);
}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java
index a647c2ff5..e9e46162c 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ImplHelper.java
@@ -23,6 +23,7 @@ import java.util.Iterator;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.kernel.FetchConfiguration;
import org.apache.openjpa.kernel.FetchState;
import org.apache.openjpa.kernel.LockManager;
import org.apache.openjpa.kernel.OpenJPAStateManager;
@@ -90,18 +91,18 @@ public class ImplHelper {
* @since 4.0
*/
public static Collection loadAll(Collection sms, StoreManager store,
- PCState state, int load, FetchState fetchState, Object context) {
+ PCState state, int load, FetchConfiguration fetch, Object context) {
Collection failed = null;
OpenJPAStateManager sm;
LockManager lm;
for (Iterator itr = sms.iterator(); itr.hasNext();) {
sm = (OpenJPAStateManager) itr.next();
+ FetchState fetchState = fetch.newFetchState();
if (sm.getManagedInstance() == null) {
if (!store.initialize(sm, state, fetchState, context))
failed = addFailedId(sm, failed);
} else if (load != StoreManager.FORCE_LOAD_NONE
|| sm.getPCState() == PCState.HOLLOW) {
-
lm = sm.getContext().getLockManager();
if (!store.load(sm, sm.getUnloaded(fetchState),
fetchState, lm.getLockLevel(sm), context))