mirror of https://github.com/apache/openjpa.git
FetchPlan with recursive scheme.
- modified select building and load cycles in JDBCStoreManager with FetchState traversal - loadAll(), findAll() methods reverted to their method signature with FetchConfiguration instead of FetchState - StateManager.postLoad checks for fetch group with postload set to true git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@425312 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
98e8533cb0
commit
884ff1b863
|
@ -441,10 +441,7 @@ public class JDBCStoreManager
|
||||||
|
|
||||||
public boolean load(OpenJPAStateManager sm, BitSet fields,
|
public boolean load(OpenJPAStateManager sm, BitSet fields,
|
||||||
FetchState fetchState, int lockLevel, Object context) {
|
FetchState fetchState, int lockLevel, Object context) {
|
||||||
JDBCFetchState jfetchState = (fetchState == null) ? (JDBCFetchState) getFetchConfiguration()
|
JDBCFetchState jfetchState = (JDBCFetchState) fetchState;
|
||||||
.newFetchState()
|
|
||||||
: (JDBCFetchState) fetchState;
|
|
||||||
|
|
||||||
JDBCFetchConfiguration jfetch = getFetchConfiguration(jfetchState);
|
JDBCFetchConfiguration jfetch = getFetchConfiguration(jfetchState);
|
||||||
|
|
||||||
// get a connection, or reuse current one
|
// get a connection, or reuse current one
|
||||||
|
@ -492,9 +489,10 @@ public class JDBCStoreManager
|
||||||
|
|
||||||
// now allow the fields to load themselves individually too
|
// now allow the fields to load themselves individually too
|
||||||
for (int i = 0, len = fields.length(); i < len; i++)
|
for (int i = 0, len = fields.length(); i < len; i++)
|
||||||
if (fields.get(i) && !sm.getLoaded().get(i))
|
if (fields.get(i) && !sm.getLoaded().get(i)) {
|
||||||
mapping.getFieldMapping(i).load(sm, this, jfetchState);
|
FieldMapping fm = mapping.getFieldMapping(i);
|
||||||
|
fm.load(sm, this, (JDBCFetchState)jfetchState.traverse(fm));
|
||||||
|
}
|
||||||
mapping.getVersion().afterLoad(sm, this);
|
mapping.getVersion().afterLoad(sm, this);
|
||||||
return true;
|
return true;
|
||||||
} catch (ClassNotFoundException cnfe) {
|
} catch (ClassNotFoundException cnfe) {
|
||||||
|
@ -514,8 +512,8 @@ public class JDBCStoreManager
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection loadAll(Collection sms, PCState state, int load,
|
public Collection loadAll(Collection sms, PCState state, int load,
|
||||||
FetchState fetchState, Object context) {
|
FetchConfiguration fetch, Object context) {
|
||||||
return ImplHelper.loadAll(sms, this, state, load, fetchState, context);
|
return ImplHelper.loadAll(sms, this, state, load, fetch, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beforeStateChange(OpenJPAStateManager sm, PCState fromState,
|
public void beforeStateChange(OpenJPAStateManager sm, PCState fromState,
|
||||||
|
@ -838,14 +836,16 @@ public class JDBCStoreManager
|
||||||
if (eagerToMany == null && fms[i].isEagerSelectToMany())
|
if (eagerToMany == null && fms[i].isEagerSelectToMany())
|
||||||
eagerToMany = fms[i];
|
eagerToMany = fms[i];
|
||||||
else
|
else
|
||||||
fms[i].loadEagerJoin(sm, this, fetchState, res);
|
fms[i].loadEagerJoin(sm, this,
|
||||||
|
(JDBCFetchState)fetchState.traverse(fms[i]), res);
|
||||||
} else if (eres != null) {
|
} else if (eres != null) {
|
||||||
processed = fms[i].loadEagerParallel(sm, this, fetchState,
|
processed = fms[i].loadEagerParallel(sm, this,
|
||||||
eres);
|
(JDBCFetchState)fetchState.traverse(fms[i]), eres);
|
||||||
if (processed != eres)
|
if (processed != eres)
|
||||||
res.putEager(fms[i], processed);
|
res.putEager(fms[i], processed);
|
||||||
} else
|
} else
|
||||||
fms[i].load(sm, this, fetchState, res);
|
fms[i].load(sm, this,
|
||||||
|
(JDBCFetchState)fetchState.traverse(fms[i]), res);
|
||||||
} finally {
|
} finally {
|
||||||
res.endDataRequest();
|
res.endDataRequest();
|
||||||
}
|
}
|
||||||
|
@ -931,11 +931,11 @@ public class JDBCStoreManager
|
||||||
int jtype;
|
int jtype;
|
||||||
int mode;
|
int mode;
|
||||||
for (int i = 0; i < fms.length; i++) {
|
for (int i = 0; i < fms.length; i++) {
|
||||||
if (!requiresSelect(fms[i], sm, fields, fetchState))
|
|
||||||
continue;
|
|
||||||
mode = fms[i].getEagerFetchMode();
|
mode = fms[i].getEagerFetchMode();
|
||||||
if (mode == fetch.EAGER_NONE)
|
if (mode == fetch.EAGER_NONE)
|
||||||
continue;
|
continue;
|
||||||
|
if (!requiresSelect(fms[i], sm, fields, fetchState))
|
||||||
|
continue;
|
||||||
|
|
||||||
// try to select with join first
|
// try to select with join first
|
||||||
jtype = (fms[i].getNullValue() == fms[i].NULL_EXCEPTION) ? sel.EAGER_INNER
|
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
|
if (sm != null && sm.getPCState() != PCState.TRANSIENT
|
||||||
&& sm.getLoaded().get(fm.getIndex()))
|
&& sm.getLoaded().get(fm.getIndex()))
|
||||||
return false;
|
return false;
|
||||||
return fetchState.requiresSelect(fm, true);
|
return fetchState.requiresFetch(fm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1059,17 +1059,19 @@ public class JDBCStoreManager
|
||||||
esel = sel.getEager(fms[i]);
|
esel = sel.getEager(fms[i]);
|
||||||
if (esel != null) {
|
if (esel != null) {
|
||||||
if (esel == sel)
|
if (esel == sel)
|
||||||
fms[i].selectEagerJoin(sel, sm, this, fetchState, eager);
|
fms[i].selectEagerJoin(sel, sm, this,
|
||||||
|
(JDBCFetchState)fetchState.traverse(fms[i]), eager);
|
||||||
else
|
else
|
||||||
fms[i].selectEagerParallel(esel, sm, this, fetchState,
|
fms[i].selectEagerParallel(esel, sm, this,
|
||||||
eager);
|
(JDBCFetchState)fetchState.traverse(fms[i]), eager);
|
||||||
seld = Math.max(0, seld);
|
seld = Math.max(0, seld);
|
||||||
} else if (requiresSelect(fms[i], sm, fields, fetchState)) {
|
} 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);
|
seld = Math.max(fseld, seld);
|
||||||
} else if (optSelect(fms[i], sel, sm, fetchState)) {
|
} else if (optSelect(fms[i], sel, sm, fetchState)) {
|
||||||
fseld = fms[i].select(sel, sm, this, fetchState,
|
fseld = fms[i].select(sel, sm, this,
|
||||||
fetch.EAGER_NONE);
|
(JDBCFetchState)fetchState.traverse(fms[i]), fetch.EAGER_NONE);
|
||||||
|
|
||||||
// don't upgrade seld to > 0 based on these fields, since
|
// don't upgrade seld to > 0 based on these fields, since
|
||||||
// they're not in the calculated field set
|
// they're not in the calculated field set
|
||||||
|
@ -1100,7 +1102,7 @@ public class JDBCStoreManager
|
||||||
.getLoaded().get(fm.getIndex()))
|
.getLoaded().get(fm.getIndex()))
|
||||||
&& fm.supportsSelect(sel, sel.TYPE_TWO_PART, sm, this,
|
&& fm.supportsSelect(sel, sel.TYPE_TWO_PART, sm, this,
|
||||||
getFetchConfiguration(fetchState)) > 0
|
getFetchConfiguration(fetchState)) > 0
|
||||||
&& fetchState.requiresSelect(fm, true);
|
&& fetchState.requiresFetch(fm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1141,12 +1143,15 @@ public class JDBCStoreManager
|
||||||
fms = subMappings[i].getDefinedFieldMappings();
|
fms = subMappings[i].getDefinedFieldMappings();
|
||||||
for (int j = 0; j < fms.length; j++) {
|
for (int j = 0; j < fms.length; j++) {
|
||||||
// make sure in one of configured fetch groups
|
// make sure in one of configured fetch groups
|
||||||
if (!fms[j].isInDefaultFetchGroup()
|
if (fetchState.requiresFetch(fms[j])
|
||||||
&& !fetch.hasFetchGroup(fms[j].getFetchGroups())
|
|| fms[j].supportsSelect(sel, sel.TYPE_TWO_PART, sm, this, fetch) <= 0)
|
||||||
&& !fetch.hasField(fms[j].getFullName())
|
|
||||||
&& (fms[j].isDefaultFetchGroupExplicit() || fms[j]
|
|
||||||
.supportsSelect(sel, sel.TYPE_TWO_PART, sm, this, fetch) <= 0))
|
|
||||||
continue;
|
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
|
// if we can join to the subclass, do so; much better chance
|
||||||
// that the field will be able to select itself without joins
|
// 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 can select with tables already selected, do it
|
||||||
if (fms[j].supportsSelect(sel, sel.TYPE_JOINLESS, sm, this,
|
if (fms[j].supportsSelect(sel, sel.TYPE_JOINLESS, sm, this,
|
||||||
fetch) > 0)
|
fetch) > 0 && fetchState.requiresFetch(fms[j]))
|
||||||
fms[j]
|
fms[j].select(sel, null, this,
|
||||||
.select(sel, null, this, fetchState, fetch.EAGER_NONE);
|
(JDBCFetchState)fetchState.traverse(fms[j]),
|
||||||
|
fetch.EAGER_NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ public class PagingResultObjectProvider
|
||||||
BitSet paged = null;
|
BitSet paged = null;
|
||||||
for (int i = 0; i < fms.length; i++) {
|
for (int i = 0; i < fms.length; i++) {
|
||||||
if (fetchState != null
|
if (fetchState != null
|
||||||
&& !fetchState.requiresSelect(fms[i], false))
|
&& !fetchState.requiresFetch(fms[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (fms[i].supportsSelect(sel, sel.EAGER_PARALLEL, null, store,
|
if (fms[i].supportsSelect(sel, sel.EAGER_PARALLEL, null, store,
|
||||||
|
|
|
@ -233,8 +233,8 @@ public abstract class AbstractStoreManager
|
||||||
* advantageous.
|
* advantageous.
|
||||||
*/
|
*/
|
||||||
public Collection loadAll(Collection sms, PCState state, int load,
|
public Collection loadAll(Collection sms, PCState state, int load,
|
||||||
FetchState fetchState, Object context) {
|
FetchConfiguration fetch, Object context) {
|
||||||
return ImplHelper.loadAll(sms, this, state, load, fetchState, context);
|
return ImplHelper.loadAll(sms, this, state, load, fetch, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -408,12 +408,9 @@ public class DataCacheStoreManager
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection loadAll(Collection sms, PCState state, int load,
|
public Collection loadAll(Collection sms, PCState state, int load,
|
||||||
FetchState fetchState, Object edata) {
|
FetchConfiguration fetch, Object edata) {
|
||||||
FetchConfiguration fetch = (fetchState == null)
|
|
||||||
? _ctx.getFetchConfiguration()
|
|
||||||
: fetchState.getFetchConfiguration();
|
|
||||||
if (isLocking(fetch))
|
if (isLocking(fetch))
|
||||||
return super.loadAll(sms, state, load, fetchState, edata);
|
return super.loadAll(sms, state, load, fetch, edata);
|
||||||
|
|
||||||
Map unloaded = null;
|
Map unloaded = null;
|
||||||
OpenJPAStateManager sm;
|
OpenJPAStateManager sm;
|
||||||
|
@ -435,7 +432,7 @@ public class DataCacheStoreManager
|
||||||
//### the 'data.type' access here probably needs
|
//### the 'data.type' access here probably needs
|
||||||
//### to be addressed for bug 511
|
//### to be addressed for bug 511
|
||||||
sm.initialize(data.getType(), state);
|
sm.initialize(data.getType(), state);
|
||||||
data.load(sm, fetchState, edata);
|
data.load(sm, fetch.newFetchState(), edata);
|
||||||
} else
|
} else
|
||||||
unloaded = addUnloaded(sm, null, unloaded);
|
unloaded = addUnloaded(sm, null, unloaded);
|
||||||
} else if (load != FORCE_LOAD_NONE
|
} else if (load != FORCE_LOAD_NONE
|
||||||
|
@ -443,6 +440,7 @@ public class DataCacheStoreManager
|
||||||
data = cache.get(sm.getObjectId());
|
data = cache.get(sm.getObjectId());
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
// load unloaded fields
|
// load unloaded fields
|
||||||
|
FetchState fetchState = fetch.newFetchState();
|
||||||
fields = sm.getUnloaded(fetchState);
|
fields = sm.getUnloaded(fetchState);
|
||||||
data.load(sm, fields, fetchState, edata);
|
data.load(sm, fields, fetchState, edata);
|
||||||
if (fields.length() > 0)
|
if (fields.length() > 0)
|
||||||
|
@ -458,7 +456,7 @@ public class DataCacheStoreManager
|
||||||
|
|
||||||
// load with delegate
|
// load with delegate
|
||||||
Collection failed = super.loadAll(unloaded.keySet(), state, load,
|
Collection failed = super.loadAll(unloaded.keySet(), state, load,
|
||||||
fetchState, edata);
|
fetch, edata);
|
||||||
if (!_ctx.getPopulateDataCache())
|
if (!_ctx.getPopulateDataCache())
|
||||||
return failed;
|
return failed;
|
||||||
|
|
||||||
|
|
|
@ -575,7 +575,7 @@ public class PCDataGenerator
|
||||||
code.invokevirtual().setMethod(FieldMetaData.class,
|
code.invokevirtual().setMethod(FieldMetaData.class,
|
||||||
"getFetchGroups", Set.class, null);
|
"getFetchGroups", Set.class, null);
|
||||||
code.invokeinterface().setMethod
|
code.invokeinterface().setMethod
|
||||||
(FetchConfiguration.class, "hasFetchGroup",
|
(FetchConfiguration.class, "hasAnyFetchGroup",
|
||||||
boolean.class, new Class[]{ Set.class });
|
boolean.class, new Class[]{ Set.class });
|
||||||
JumpInstruction ifins = code.ifne();
|
JumpInstruction ifins = code.ifne();
|
||||||
code.aload().setLocal(fetch);
|
code.aload().setLocal(fetch);
|
||||||
|
|
|
@ -694,11 +694,13 @@ public class BrokerImpl
|
||||||
int flags = OID_COPY | OID_ALLOW_NEW | OID_NODELETED;
|
int flags = OID_COPY | OID_ALLOW_NEW | OID_NODELETED;
|
||||||
if (!validate)
|
if (!validate)
|
||||||
flags |= OID_NOVALIDATE;
|
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,
|
public Object find(Object oid, FetchState fetchState, BitSet exclude,
|
||||||
Object edata, int flags) {
|
Object edata, int flags) {
|
||||||
|
if (fetchState == null)
|
||||||
|
fetchState = _fc.newFetchState ();
|
||||||
return find(oid, fetchState, exclude, edata, flags, null);
|
return find(oid, fetchState, exclude, edata, flags, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,8 +719,6 @@ public class BrokerImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
beginOperation(true);
|
beginOperation(true);
|
||||||
if (fetchState == null)
|
|
||||||
fetchState = _fc.newFetchState();
|
|
||||||
try {
|
try {
|
||||||
assertNontransactionalRead();
|
assertNontransactionalRead();
|
||||||
|
|
||||||
|
@ -842,18 +842,18 @@ public class BrokerImpl
|
||||||
int flags = OID_COPY | OID_ALLOW_NEW | OID_NODELETED;
|
int flags = OID_COPY | OID_ALLOW_NEW | OID_NODELETED;
|
||||||
if (!validate)
|
if (!validate)
|
||||||
flags |= OID_NOVALIDATE;
|
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) {
|
BitSet exclude, Object edata, int flags) {
|
||||||
return findAll(oids, fetchState, exclude, edata, flags, null);
|
return findAll(oids, fetch, exclude, edata, flags, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal finder.
|
* Internal finder.
|
||||||
*/
|
*/
|
||||||
protected Object[] findAll(Collection oids, FetchState fetchState,
|
protected Object[] findAll(Collection oids, FetchConfiguration fetch,
|
||||||
BitSet exclude, Object edata, int flags, FindCallbacks call) {
|
BitSet exclude, Object edata, int flags, FindCallbacks call) {
|
||||||
// throw any exceptions for null oids up immediately
|
// throw any exceptions for null oids up immediately
|
||||||
if (oids == null)
|
if (oids == null)
|
||||||
|
@ -867,9 +867,6 @@ public class BrokerImpl
|
||||||
_loading = new HashMap((int) (oids.size() * 1.33 + 1));
|
_loading = new HashMap((int) (oids.size() * 1.33 + 1));
|
||||||
if (call == null)
|
if (call == null)
|
||||||
call = this;
|
call = this;
|
||||||
if (fetchState == null)
|
|
||||||
fetchState = _fc.newFetchState();
|
|
||||||
FetchConfiguration fetch = fetchState.getFetchConfiguration();
|
|
||||||
beginOperation(true);
|
beginOperation(true);
|
||||||
try {
|
try {
|
||||||
assertNontransactionalRead();
|
assertNontransactionalRead();
|
||||||
|
@ -915,7 +912,7 @@ public class BrokerImpl
|
||||||
PCState state = (transState) ? PCState.PCLEAN
|
PCState state = (transState) ? PCState.PCLEAN
|
||||||
: PCState.PNONTRANS;
|
: PCState.PNONTRANS;
|
||||||
Collection failed = _store.loadAll(load, state,
|
Collection failed = _store.loadAll(load, state,
|
||||||
StoreManager.FORCE_LOAD_NONE, fetchState, edata);
|
StoreManager.FORCE_LOAD_NONE, _fc, edata);
|
||||||
|
|
||||||
// set failed instances to null
|
// set failed instances to null
|
||||||
if (failed != null && !failed.isEmpty()) {
|
if (failed != null && !failed.isEmpty()) {
|
||||||
|
@ -937,8 +934,8 @@ public class BrokerImpl
|
||||||
sm = (StateManagerImpl) _loading.get(oid);
|
sm = (StateManagerImpl) _loading.get(oid);
|
||||||
if (sm != null && requiresLoad(sm, true, edata, flags)) {
|
if (sm != null && requiresLoad(sm, true, edata, flags)) {
|
||||||
try {
|
try {
|
||||||
sm.load(fetchState, StateManagerImpl.LOAD_FGS, exclude,
|
sm.load(fetch.newFetchState(), StateManagerImpl.LOAD_FGS,
|
||||||
edata, false);
|
exclude, edata, false);
|
||||||
if (active) {
|
if (active) {
|
||||||
_lm.lock(sm, level, fetch.getLockTimeout(), edata);
|
_lm.lock(sm, level, fetch.getLockTimeout(), edata);
|
||||||
sm.readLocked(level, fetch.getWriteLockLevel());
|
sm.readLocked(level, fetch.getWriteLockLevel());
|
||||||
|
@ -2687,7 +2684,7 @@ public class BrokerImpl
|
||||||
// refresh all
|
// refresh all
|
||||||
if (load != null) {
|
if (load != null) {
|
||||||
Collection failed = _store.loadAll(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())
|
if (failed != null && !failed.isEmpty())
|
||||||
exceps = add(exceps, newObjectNotFoundException(failed));
|
exceps = add(exceps, newObjectNotFoundException(failed));
|
||||||
|
|
||||||
|
@ -2812,8 +2809,7 @@ public class BrokerImpl
|
||||||
if (load != null) {
|
if (load != null) {
|
||||||
int mode = (dfgOnly) ? _store.FORCE_LOAD_DFG
|
int mode = (dfgOnly) ? _store.FORCE_LOAD_DFG
|
||||||
: _store.FORCE_LOAD_ALL;
|
: _store.FORCE_LOAD_ALL;
|
||||||
failed = _store.loadAll(load, null, mode, _fc.newFetchState(),
|
failed = _store.loadAll(load, null, mode, _fc, null);
|
||||||
null);
|
|
||||||
if (failed != null && !failed.isEmpty())
|
if (failed != null && !failed.isEmpty())
|
||||||
exceps = add(exceps, newObjectNotFoundException(failed));
|
exceps = add(exceps, newObjectNotFoundException(failed));
|
||||||
}
|
}
|
||||||
|
@ -3196,7 +3192,7 @@ public class BrokerImpl
|
||||||
Collection failed = null;
|
Collection failed = null;
|
||||||
if (load != null) {
|
if (load != null) {
|
||||||
failed = _store.loadAll(load, null, _store.FORCE_LOAD_NONE,
|
failed = _store.loadAll(load, null, _store.FORCE_LOAD_NONE,
|
||||||
_fc.newFetchState(), null);
|
_fc, null);
|
||||||
if (failed != null && !failed.isEmpty())
|
if (failed != null && !failed.isEmpty())
|
||||||
exceps = add(exceps,
|
exceps = add(exceps,
|
||||||
newObjectNotFoundException(failed));
|
newObjectNotFoundException(failed));
|
||||||
|
@ -4087,7 +4083,7 @@ public class BrokerImpl
|
||||||
Object oid = ApplicationIds.create(pc, meta);
|
Object oid = ApplicationIds.create(pc, meta);
|
||||||
if (oid == null)
|
if (oid == null)
|
||||||
return false;
|
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) {
|
public OpenJPAStateManager getStateManager(Object obj) {
|
||||||
|
|
|
@ -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) {
|
BitSet exclude, Object edata, int flags) {
|
||||||
try {
|
try {
|
||||||
return _broker.findAll(oids, fetchState, exclude, edata, flags);
|
return _broker.findAll(oids, fetch, exclude, edata, flags);
|
||||||
} catch (RuntimeException re) {
|
} catch (RuntimeException re) {
|
||||||
throw translate(re);
|
throw translate(re);
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,9 +229,9 @@ public class DelegatingFetchConfiguration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasFetchGroup(Set groups) {
|
public boolean hasAnyFetchGroup(Set groups) {
|
||||||
try {
|
try {
|
||||||
return _fetch.hasFetchGroup(groups);
|
return _fetch.hasAnyFetchGroup(groups);
|
||||||
} catch (RuntimeException re) {
|
} catch (RuntimeException re) {
|
||||||
throw translate(re);
|
throw translate(re);
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,8 +114,8 @@ public abstract class DelegatingStoreManager
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection loadAll(Collection sms, PCState state, int load,
|
public Collection loadAll(Collection sms, PCState state, int load,
|
||||||
FetchState fetchState, Object context) {
|
FetchConfiguration fetch, Object context) {
|
||||||
return _store.loadAll(sms, state, load, fetchState, context);
|
return _store.loadAll(sms, state, load, fetch, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beforeStateChange(OpenJPAStateManager sm, PCState fromState,
|
public void beforeStateChange(OpenJPAStateManager sm, PCState fromState,
|
||||||
|
|
|
@ -223,7 +223,7 @@ public class DetachManager
|
||||||
FieldMetaData[] fmds = sm.getMetaData().getFields();
|
FieldMetaData[] fmds = sm.getMetaData().getFields();
|
||||||
for (int i = 0; i < fmds.length; i++) {
|
for (int i = 0; i < fmds.length; i++) {
|
||||||
if (fmds[i].isPrimaryKey() || fmds[i].isInDefaultFetchGroup()
|
if (fmds[i].isPrimaryKey() || fmds[i].isInDefaultFetchGroup()
|
||||||
|| fetch.hasFetchGroup(fmds[i].getFetchGroups())
|
|| fetch.hasAnyFetchGroup(fmds[i].getFetchGroups())
|
||||||
|| fetch.hasField(fmds[i].getFullName()))
|
|| fetch.hasField(fmds[i].getFullName()))
|
||||||
idxs.set(i);
|
idxs.set(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,9 +136,10 @@ public class DetachedStateManager
|
||||||
load.set(i);
|
load.set(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FetchConfiguration fc = broker.getFetchConfiguration();
|
||||||
|
FetchState fetchState = fc.newFetchState();
|
||||||
|
sm.loadFields(load, fetchState, fc.getWriteLockLevel(), null, true);
|
||||||
|
|
||||||
sm.loadFields(load, null, broker.getFetchConfiguration().
|
|
||||||
getWriteLockLevel(), null, true);
|
|
||||||
}
|
}
|
||||||
sm.setVersion(_version);
|
sm.setVersion(_version);
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ public interface FetchConfiguration
|
||||||
public static final String FETCH_GROUP_ALL =
|
public static final String FETCH_GROUP_ALL =
|
||||||
"org.apache.openjpa.kernel.FetchConfiguration.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;
|
* Return the context assiciated with this configuration;
|
||||||
* may be null if it has not been set or this object has been serialized.
|
* 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
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public boolean hasFetchGroup(Set groups);
|
public boolean hasAnyFetchGroup(Set groups);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds <code>group</code> to the set of fetch group names to
|
* Adds <code>group</code> to the set of fetch group names to
|
||||||
|
|
|
@ -108,6 +108,7 @@ public class FetchConfigurationImpl
|
||||||
|
|
||||||
public void copy(FetchConfiguration fetch) {
|
public void copy(FetchConfiguration fetch) {
|
||||||
setFetchBatchSize(fetch.getFetchBatchSize());
|
setFetchBatchSize(fetch.getFetchBatchSize());
|
||||||
|
setMaxFetchDepth(fetch.getMaxFetchDepth());
|
||||||
setQueryCache(fetch.getQueryCache());
|
setQueryCache(fetch.getQueryCache());
|
||||||
setFlushBeforeQueries(fetch.getFlushBeforeQueries());
|
setFlushBeforeQueries(fetch.getFlushBeforeQueries());
|
||||||
setLockTimeout(fetch.getLockTimeout());
|
setLockTimeout(fetch.getLockTimeout());
|
||||||
|
@ -172,11 +173,11 @@ public class FetchConfigurationImpl
|
||||||
|
|
||||||
public synchronized boolean hasFetchGroup(String group) {
|
public synchronized boolean hasFetchGroup(String group) {
|
||||||
return _fetchGroups != null
|
return _fetchGroups != null
|
||||||
&& ((group != null && _fetchGroups.contains(group))
|
&& (_fetchGroups.contains(group)
|
||||||
|| _fetchGroups.contains(FETCH_GROUP_ALL));
|
|| _fetchGroups.contains(FETCH_GROUP_ALL));
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean hasFetchGroup(Set groups) {
|
public synchronized boolean hasAnyFetchGroup(Set groups) {
|
||||||
if (_fetchGroups != null && groups != null) {
|
if (_fetchGroups != null && groups != null) {
|
||||||
Iterator iter = groups.iterator();
|
Iterator iter = groups.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2006 The Apache Software Foundation.
|
* Copyright 2006 The Apache Software Foundation.
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -15,16 +12,24 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.openjpa.kernel;
|
package org.apache.openjpa.kernel;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.openjpa.meta.FieldMetaData;
|
import org.apache.openjpa.meta.FieldMetaData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the decision to include fields for selection or loading during
|
* Defines the decision to include fields for selection or loading during
|
||||||
* a fetch operation.
|
* a fetch operation.
|
||||||
|
* A state is resulted by traversal of a relationship except the <em>root</em>
|
||||||
|
* state.
|
||||||
*
|
*
|
||||||
* @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
|
* @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public interface FetchState {
|
public interface FetchState
|
||||||
|
extends Serializable, Cloneable {
|
||||||
|
|
||||||
|
public static final int INFINITE_DEPTH = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the immutable fetch configuration this receiver is based on.
|
* Returns the immutable fetch configuration this receiver is based on.
|
||||||
|
@ -32,24 +37,16 @@ public interface FetchState {
|
||||||
public FetchConfiguration getFetchConfiguration();
|
public FetchConfiguration getFetchConfiguration();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Affirms if the given field requires to be selected in the context
|
* Affirms if the given field requires to be fetched in the context
|
||||||
* of current fetch operation.
|
* of current fetch operation.
|
||||||
* The response can be stateful as the same field argument would generate
|
|
||||||
* different responses on different invocation based on the current
|
|
||||||
* state of this receiver if changeState flag is true.
|
|
||||||
*
|
*
|
||||||
* @param fm field metadata. must not be null.
|
* @param fm field metadata. must not be null.
|
||||||
* @param changeState true implies that the state of the receiver will
|
|
||||||
* change due to invocation.
|
|
||||||
*/
|
*/
|
||||||
public boolean requiresSelect(FieldMetaData fm, boolean changeState);
|
public boolean requiresFetch(FieldMetaData fm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Affirms if the given field of the given instance requires to be loaded
|
* Affirms if the given field of the given instance requires to be loaded
|
||||||
* in the context of current fetch operation.
|
* in the context of current fetch operation.
|
||||||
* The response is stateful as the same arguments would generate different
|
|
||||||
* responses on different invocation based on the current state of this
|
|
||||||
* receiver.
|
|
||||||
*
|
*
|
||||||
* @param sm state manager being populated
|
* @param sm state manager being populated
|
||||||
* @param fm field metadata
|
* @param fm field metadata
|
||||||
|
@ -57,12 +54,82 @@ public interface FetchState {
|
||||||
public boolean requiresLoad(OpenJPAStateManager sm, FieldMetaData fm);
|
public boolean requiresLoad(OpenJPAStateManager sm, FieldMetaData fm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Affirms if the given field is to be loaded as default. The field itself
|
* Traverse the given field to generate (possibly) a new state.
|
||||||
* is aware of whether it belongs to the default fetch group. This method
|
|
||||||
* adds an extra constraint to verify that current configuration includes
|
|
||||||
* default fetch group.
|
|
||||||
*
|
*
|
||||||
* @param fm field metadata
|
* @param fm
|
||||||
|
* @return a new state resulting out of traversal. If the given field is
|
||||||
|
* not a relation then return itself.
|
||||||
*/
|
*/
|
||||||
public boolean isDefault(FieldMetaData fm);
|
public FetchState traverse (FieldMetaData fm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the available depth i.e. number of relations that can be traveresed
|
||||||
|
* from this receiver.
|
||||||
|
*
|
||||||
|
* @return a positive integer with positive infinity designated as
|
||||||
|
* <code>-1</code>.
|
||||||
|
*/
|
||||||
|
public int getAvailableFetchDepth ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the root state where this receiver is derived from.
|
||||||
|
* @return itself if the state is not derived from another state.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public FetchState getRoot ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affirms if this receiver is the root state i.e. not derived as a result
|
||||||
|
* of traversing a relationship.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public boolean isRoot ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the parent state.
|
||||||
|
* @return can be null for the root state.
|
||||||
|
*/
|
||||||
|
public FetchState getParent ();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an ordered list of states from this receiver to its root.
|
||||||
|
*
|
||||||
|
* @return the order starts from this receiver and ends in the
|
||||||
|
* root. An empty list if this receiver is the root.
|
||||||
|
*/
|
||||||
|
public List getPath ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an ordered list of relation fields from this receiver to its root.
|
||||||
|
* These relations denote the path traversals from the root that resulted
|
||||||
|
* in the current state.
|
||||||
|
*
|
||||||
|
* @return the list starts from relation traversal of which resulted in this
|
||||||
|
* receiver and ends in the relation traversed from the root.
|
||||||
|
* An empty list, if this receiver itself is the root.
|
||||||
|
*/
|
||||||
|
public List getRelationPath ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of times the given field is traversed to arrive
|
||||||
|
* at this state.
|
||||||
|
*
|
||||||
|
* @param fm
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getCurrentRecursionDepth (FieldMetaData fm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the recursion depth of the given field.
|
||||||
|
*
|
||||||
|
* @param fm a relation field
|
||||||
|
* @return If the field has multiple fetch groups in the current
|
||||||
|
* configuration, then the recursion depth is maximum of all the recursion
|
||||||
|
* depths.
|
||||||
|
* The default recursion depth, if none is explictly specified, is 1.
|
||||||
|
* The infinite i.e. unlimited recursion depth is designated as
|
||||||
|
* <code>-1</code>
|
||||||
|
*/
|
||||||
|
public int getRecursionDepth (FieldMetaData fm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2006 The Apache Software Foundation.
|
* Copyright 2006 The Apache Software Foundation.
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -18,17 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.openjpa.kernel;
|
package org.apache.openjpa.kernel;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.openjpa.meta.ClassMetaData;
|
import org.apache.openjpa.enhance.StateManager;
|
||||||
import org.apache.openjpa.meta.FetchGroup;
|
import org.apache.openjpa.meta.FetchGroup;
|
||||||
import org.apache.openjpa.meta.FieldMetaData;
|
import org.apache.openjpa.meta.FieldMetaData;
|
||||||
import org.apache.openjpa.meta.JavaTypes;
|
import org.apache.openjpa.util.InternalException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds dynamic status of fetch operation. Decides whether a field
|
* Holds dynamic status of fetch operation. Decides whether a field
|
||||||
|
@ -37,18 +29,12 @@ import org.apache.openjpa.meta.JavaTypes;
|
||||||
* @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
|
* @author <A HREF="mailto:pinaki.poddar@gmail.com>Pinaki Poddar</A>
|
||||||
* @nojavadoc
|
* @nojavadoc
|
||||||
*/
|
*/
|
||||||
public class FetchStateImpl
|
public class FetchStateImpl implements FetchState {
|
||||||
implements FetchState, Serializable {
|
|
||||||
|
|
||||||
private final FetchConfiguration _config;
|
private final FetchConfiguration _config;
|
||||||
|
private FetchState _parent;
|
||||||
private Map _selectTraversals;
|
private FieldMetaData _relation;
|
||||||
private Map _loadTraversals;
|
private int _availableDepth;
|
||||||
private Map _recursionDepths;
|
|
||||||
private Map _depths;
|
|
||||||
private int _depth;
|
|
||||||
private final Set _knownExcludes;
|
|
||||||
private static final int INFINITE_DEPTH = -1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supply configuration.
|
* Supply configuration.
|
||||||
|
@ -56,72 +42,105 @@ public class FetchStateImpl
|
||||||
* @param fc must not be null.
|
* @param fc must not be null.
|
||||||
*/
|
*/
|
||||||
public FetchStateImpl(FetchConfiguration fc) {
|
public FetchStateImpl(FetchConfiguration fc) {
|
||||||
super();
|
|
||||||
_config = fc;
|
_config = fc;
|
||||||
_knownExcludes = new HashSet();
|
_parent = null;
|
||||||
_selectTraversals = new HashMap();
|
_relation = null;
|
||||||
_loadTraversals = new HashMap();
|
_availableDepth = _config.getMaxFetchDepth();
|
||||||
_depths = new HashMap();
|
|
||||||
_recursionDepths = new HashMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FetchConfiguration getFetchConfiguration() {
|
public FetchConfiguration getFetchConfiguration() {
|
||||||
return _config;
|
return _config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDefault(FieldMetaData fm) {
|
public FetchState getParent () {
|
||||||
return _config.hasFetchGroup(FetchGroup.getDefaultGroupName())
|
return _parent;
|
||||||
&& fm.isInDefaultFetchGroup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requiresSelect(FieldMetaData fm, boolean changeState) {
|
public boolean isRoot () {
|
||||||
if (_knownExcludes.contains(fm))
|
return _parent == null;
|
||||||
return false;
|
}
|
||||||
boolean selectable = isDefault(fm)
|
|
||||||
|| _config.hasFetchGroup(fm.getFetchGroups())
|
|
||||||
|| _config.hasField(fm.getFullName());
|
|
||||||
if (!selectable)
|
|
||||||
_knownExcludes.add(fm);
|
|
||||||
|
|
||||||
if (selectable && JavaTypes.maybePC(fm)) // relation field
|
public FetchState getRoot() {
|
||||||
{
|
return (isRoot()) ? this : getParent().getRoot();
|
||||||
if (canTraverse(fm)) {
|
}
|
||||||
if (changeState)
|
|
||||||
traverse(fm);
|
public int getAvailableFetchDepth() {
|
||||||
} else
|
return _availableDepth;
|
||||||
selectable = false;
|
}
|
||||||
|
|
||||||
|
public List getPath () {
|
||||||
|
if (isRoot())
|
||||||
|
return Collections.EMPTY_LIST;
|
||||||
|
List result = new ArrayList();
|
||||||
|
result.add (this);
|
||||||
|
return ((FetchStateImpl)_parent).trackPath (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List trackPath (List path) {
|
||||||
|
if (isRoot())
|
||||||
|
return path;
|
||||||
|
path.add(this);
|
||||||
|
return ((FetchStateImpl)_parent).trackPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List getRelationPath () {
|
||||||
|
if (isRoot())
|
||||||
|
return Collections.EMPTY_LIST;
|
||||||
|
List result = new ArrayList();
|
||||||
|
result.add (_relation);
|
||||||
|
return ((FetchStateImpl)_parent).trackRelationPath (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List trackRelationPath (List path) {
|
||||||
|
if (isRoot())
|
||||||
|
return path;
|
||||||
|
path.add(_relation);
|
||||||
|
return ((FetchStateImpl)_parent).trackRelationPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getCurrentRecursionDepth (FieldMetaData fm) {
|
||||||
|
if (isRoot())
|
||||||
|
return 0;
|
||||||
|
int rd = (_relation == fm) ? 1 : 0;
|
||||||
|
|
||||||
|
return rd + _parent.getCurrentRecursionDepth(fm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDefault(FieldMetaData fm) {
|
||||||
|
return (_config.hasFetchGroup(FetchConfiguration.FETCH_GROUP_DEFAULT)
|
||||||
|
&& fm.isInDefaultFetchGroup())
|
||||||
|
|| _config.hasFetchGroup(FetchConfiguration.FETCH_GROUP_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean requiresFetch(FieldMetaData fm) {
|
||||||
|
boolean selectable = isDefault(fm)
|
||||||
|
|| _config.hasAnyFetchGroup(fm.getFetchGroups())
|
||||||
|
|| _config.hasField(fm.getFullName());
|
||||||
|
if (selectable && isRelation(fm)) {
|
||||||
|
int rd = getRecursionDepth(fm);
|
||||||
|
int crd = getCurrentRecursionDepth(fm);
|
||||||
|
selectable = (_availableDepth==INFINITE_DEPTH || _availableDepth>0)
|
||||||
|
&& ( rd == INFINITE_DEPTH || crd <rd);
|
||||||
}
|
}
|
||||||
return selectable;
|
return selectable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requiresLoad(OpenJPAStateManager sm, FieldMetaData fm) {
|
public boolean requiresLoad(OpenJPAStateManager sm, FieldMetaData fm) {
|
||||||
|
if (sm!=null && sm.getLoaded().get(fm.getIndex()))
|
||||||
|
return false;
|
||||||
boolean loadable = isDefault(fm)
|
boolean loadable = isDefault(fm)
|
||||||
|| _config.hasFetchGroup(fm.getFetchGroups())
|
|| _config.hasAnyFetchGroup(fm.getFetchGroups())
|
||||||
|| _config.hasField(fm.getFullName());
|
|| _config.hasField(fm.getFullName());
|
||||||
if (!loadable)
|
if (loadable && isRelation(fm)) {
|
||||||
_knownExcludes.add(fm);
|
int rd = getRecursionDepth(fm);
|
||||||
// relation field
|
int crd = getCurrentRecursionDepth(fm);
|
||||||
if (loadable && JavaTypes.maybePC(fm)) {
|
loadable = (_availableDepth==INFINITE_DEPTH || _availableDepth>0)
|
||||||
int d = getLoadCount(fm);
|
&& (rd == INFINITE_DEPTH || crd<rd);
|
||||||
loadable = (d < (getTraversalCount(fm) - 1));
|
|
||||||
if (loadable)
|
|
||||||
_loadTraversals.put(fm, new Integer(d + 1));
|
|
||||||
}
|
}
|
||||||
return loadable;
|
return loadable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the recusion depth for the given field.
|
|
||||||
*
|
|
||||||
* @param fm is the field to look for
|
|
||||||
* @return 0 if the field does not appear in the given map.
|
|
||||||
*/
|
|
||||||
protected int getRecursionDepth(FieldMetaData fm) {
|
|
||||||
if (_recursionDepths.containsKey(fm)) {
|
|
||||||
return ((Integer) _recursionDepths.get(fm)).intValue();
|
|
||||||
}
|
|
||||||
return initalizeRecusrionDepth(fm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the recursion depth for the given field as the maximum recusion
|
* Sets the recursion depth for the given field as the maximum recusion
|
||||||
|
@ -131,17 +150,16 @@ public class FetchStateImpl
|
||||||
* @return maximum recursion depth across common fetch groups. -1 is treated
|
* @return maximum recursion depth across common fetch groups. -1 is treated
|
||||||
* as positive infinity.
|
* as positive infinity.
|
||||||
*/
|
*/
|
||||||
protected int initalizeRecusrionDepth(FieldMetaData fm) {
|
public int getRecursionDepth(FieldMetaData fm) {
|
||||||
Set commonFGNs = new HashSet();
|
Set commonFGNs = new HashSet();
|
||||||
commonFGNs.addAll(_config.getFetchGroups());
|
commonFGNs.addAll(_config.getFetchGroups());
|
||||||
commonFGNs.retainAll(fm.getFetchGroups());
|
commonFGNs.retainAll(fm.getFetchGroups());
|
||||||
|
int dMax =
|
||||||
int dMax = (commonFGNs.isEmpty()) ? FetchGroup.DEFAULT_RECURSION_DEPTH
|
(commonFGNs.isEmpty()) ? FetchGroup.DEFAULT_RECURSION_DEPTH : 0;
|
||||||
: 0;
|
|
||||||
Iterator i = commonFGNs.iterator();
|
Iterator i = commonFGNs.iterator();
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
FetchGroup fg = fm.getDeclaringMetaData()
|
FetchGroup fg = fm.getDeclaringMetaData()
|
||||||
.getFetchGroup(i.next().toString(), false);
|
.getFetchGroup(i.next().toString());
|
||||||
int d = fg.getDepthFor(fm);
|
int d = fg.getDepthFor(fm);
|
||||||
if (d == INFINITE_DEPTH) {
|
if (d == INFINITE_DEPTH) {
|
||||||
dMax = INFINITE_DEPTH;
|
dMax = INFINITE_DEPTH;
|
||||||
|
@ -149,57 +167,68 @@ public class FetchStateImpl
|
||||||
}
|
}
|
||||||
dMax = Math.max(d, dMax);
|
dMax = Math.max(d, dMax);
|
||||||
}
|
}
|
||||||
_recursionDepths.put(fm, new Integer(dMax));
|
int maxDepth = _config.getMaxFetchDepth();
|
||||||
|
if (maxDepth != INFINITE_DEPTH)
|
||||||
|
if (dMax != INFINITE_DEPTH)
|
||||||
|
dMax = Math.min (maxDepth, dMax);
|
||||||
|
else
|
||||||
|
dMax = maxDepth;
|
||||||
|
|
||||||
return dMax;
|
return dMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean canTraverse(FieldMetaData fm) {
|
|
||||||
int maxDepth = _config.getMaxFetchDepth();
|
|
||||||
if (maxDepth != INFINITE_DEPTH && _depth > maxDepth)
|
|
||||||
return false;
|
|
||||||
int sourceDepth = getDepth(fm.getDeclaringMetaData());
|
|
||||||
int traversalCount = getTraversalCount(fm);
|
|
||||||
int recursionDepth = getRecursionDepth(fm);
|
|
||||||
int newtargetDepth = sourceDepth + traversalCount + 1;
|
|
||||||
boolean isRecursive = fm.getDeclaringMetaData() ==
|
|
||||||
fm.getDeclaredTypeMetaData();
|
|
||||||
boolean traversable = (maxDepth == INFINITE_DEPTH)
|
|
||||||
|| (recursionDepth == INFINITE_DEPTH);
|
|
||||||
if (isRecursive)
|
|
||||||
traversable = traversable || (traversalCount < recursionDepth);
|
|
||||||
else
|
|
||||||
traversable = traversable || (newtargetDepth <= maxDepth);
|
|
||||||
|
|
||||||
return traversable;
|
public FetchState traverse(FieldMetaData fm) {
|
||||||
|
if (isRelation(fm)) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FetchStateImpl clone = (FetchStateImpl)clone();
|
||||||
|
clone._parent = this;
|
||||||
|
clone._relation = fm;
|
||||||
|
clone._availableDepth = reduce(_availableDepth);
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void traverse(FieldMetaData fm) {
|
|
||||||
int sourceDepth = getDepth(fm.getDeclaringMetaData());
|
int reduce (int d) {
|
||||||
int traversalCount = getTraversalCount(fm);
|
if (d==0)
|
||||||
boolean isRecursive = fm.getDeclaringMetaData() ==
|
return 0;//throw new InternalException(this.toString());
|
||||||
fm.getDeclaredTypeMetaData();
|
if (d==INFINITE_DEPTH)
|
||||||
if (!isRecursive) {
|
return INFINITE_DEPTH;
|
||||||
int newDepth = sourceDepth + traversalCount;
|
|
||||||
_depths.put(fm.getDeclaredTypeMetaData(), new Integer(newDepth));
|
return d-1;
|
||||||
_depth = Math.max(_depth, newDepth);
|
|
||||||
}
|
|
||||||
_selectTraversals.put(fm, new Integer(traversalCount + 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int getTraversalCount(FieldMetaData fm) {
|
protected boolean isRelation (FieldMetaData fm) {
|
||||||
Integer n = (Integer) _selectTraversals.get(fm);
|
return fm != null &&
|
||||||
return (n == null) ? 0 : n.intValue();
|
(fm.isDeclaredTypePC()
|
||||||
|
|| (fm.getElement() != null && fm.getElement().isTypePC())
|
||||||
|
|| (fm.getKey() != null && fm.getKey().isTypePC())
|
||||||
|
|| (fm.getValue() != null && fm.getValue().isTypePC()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int getLoadCount(FieldMetaData fm) {
|
public String toString () {
|
||||||
Integer n = (Integer) _loadTraversals.get(fm);
|
return System.identityHashCode(this) + "("+_availableDepth+"): "
|
||||||
return (n == null) ? 0 : n.intValue();
|
+ printPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getDepth(ClassMetaData cm) {
|
private String printPath ()
|
||||||
if (_depths.containsKey(cm))
|
{
|
||||||
return ((Integer) _depths.get(cm)).intValue();
|
List path = getRelationPath();
|
||||||
return 0;
|
if (path.isEmpty())
|
||||||
|
return "";
|
||||||
|
StringBuffer tmp = new StringBuffer();
|
||||||
|
Iterator i = path.iterator();
|
||||||
|
tmp.append(((FieldMetaData)i.next()).getName());
|
||||||
|
for (;i.hasNext();)
|
||||||
|
tmp.append(".").append(((FieldMetaData)i.next()).getName());
|
||||||
|
return tmp.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,8 +102,7 @@ class PNonTransState
|
||||||
if (context.getDirty().length() > 0)
|
if (context.getDirty().length() > 0)
|
||||||
context.saveFields(true);
|
context.saveFields(true);
|
||||||
context.clearFields();
|
context.clearFields();
|
||||||
context.load(context.getBroker().getFetchConfiguration().
|
context.load(null, context.LOAD_FGS, null, null, true);
|
||||||
newFetchState(), context.LOAD_FGS, null, null, true);
|
|
||||||
}
|
}
|
||||||
return PDIRTY;
|
return PDIRTY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,14 +18,7 @@ package org.apache.openjpa.kernel;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectOutput;
|
import java.io.ObjectOutput;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
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 org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||||
|
@ -325,6 +318,8 @@ public class StateManagerImpl
|
||||||
if (!forWrite && (!isPersistent() || isNew() || isDeleted()))
|
if (!forWrite && (!isPersistent() || isNew() || isDeleted()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (fetchState==null)
|
||||||
|
fetchState = _broker.getFetchConfiguration().newFetchState();
|
||||||
// if any fields being loaded, do state transitions for read
|
// if any fields being loaded, do state transitions for read
|
||||||
BitSet fields = getUnloadedInternal(fetchState, loadMode, exclude);
|
BitSet fields = getUnloadedInternal(fetchState, loadMode, exclude);
|
||||||
boolean active = _broker.isActive();
|
boolean active = _broker.isActive();
|
||||||
|
@ -2760,8 +2755,8 @@ public class StateManagerImpl
|
||||||
|
|
||||||
protected void loadField(int field, int lockLevel, boolean forWrite,
|
protected void loadField(int field, int lockLevel, boolean forWrite,
|
||||||
boolean fgs) {
|
boolean fgs) {
|
||||||
loadField(field, _broker.getFetchConfiguration().newFetchState(),
|
FetchConfiguration fc = _broker.getFetchConfiguration();
|
||||||
lockLevel, forWrite, fgs);
|
loadField(field, fc.newFetchState(),lockLevel, forWrite, fgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2799,7 +2794,7 @@ public class StateManagerImpl
|
||||||
// call this method even if there are no unloaded fields; loadFields
|
// call this method even if there are no unloaded fields; loadFields
|
||||||
// takes care of things like loading version info and setting PC
|
// takes care of things like loading version info and setting PC
|
||||||
// flags
|
// 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?
|
// is this field in the dfg?
|
||||||
FieldMetaData[] fmds = _meta.getDefaultFetchGroupFields();
|
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;
|
boolean isLoaded = true;
|
||||||
for (int i = 0; isLoaded && i < fmds.length; i++)
|
for (int i = 0; isLoaded && i < fmds.length; i++)
|
||||||
if (!_loaded.get(fmds[i].getIndex())
|
if (!_loaded.get(fmds[i].getIndex())
|
||||||
&& requiredByDefault(fmds[i], fetchState))
|
&& requiresPostLoadCallabck(fmds[i], fetchState))
|
||||||
isLoaded = false;
|
isLoaded = false;
|
||||||
if (isLoaded) {
|
if (isLoaded) {
|
||||||
_flags |= FLAG_DFG;
|
_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)
|
if (fm == null)
|
||||||
return false;
|
return false;
|
||||||
if (fetchState == null)
|
Set fetchGroups = fm.getFetchGroups();
|
||||||
return fm.isInDefaultFetchGroup()
|
for (Iterator i = fetchGroups.iterator(); i.hasNext();)
|
||||||
&& _broker.getFetchConfiguration().hasFetchGroup
|
{
|
||||||
(FetchGroup.getDefaultGroupName());
|
String fg = i.next().toString();
|
||||||
else
|
if (_broker.getFetchConfiguration().hasFetchGroup(fg)
|
||||||
return fetchState.isDefault(fm);
|
&& fm.getDeclaringMetaData().getFetchGroup(fg).isPostLoad())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -143,7 +143,7 @@ public interface StoreContext {
|
||||||
*
|
*
|
||||||
* @see #find(Object,FetchState,BitSet,Object,int)
|
* @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);
|
BitSet exclude, Object edata, int flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -210,7 +210,7 @@ public interface StoreManager
|
||||||
* @see org.apache.openjpa.util.ImplHelper#loadAll
|
* @see org.apache.openjpa.util.ImplHelper#loadAll
|
||||||
*/
|
*/
|
||||||
public Collection loadAll(Collection sms, PCState state, int load,
|
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
|
* Notification that the given state manager is about to change its
|
||||||
|
|
|
@ -130,7 +130,7 @@ class VersionAttachStrategy
|
||||||
break;
|
break;
|
||||||
case DETACH_FGS:
|
case DETACH_FGS:
|
||||||
if (fmds[i].isInDefaultFetchGroup()
|
if (fmds[i].isInDefaultFetchGroup()
|
||||||
|| fetch.hasFetchGroup(fmds[i].getFetchGroups())
|
|| fetch.hasAnyFetchGroup(fmds[i].getFetchGroups())
|
||||||
|| fetch.hasField(fmds[i].getFullName()))
|
|| fetch.hasField(fmds[i].getFullName()))
|
||||||
attachField(manager, toAttach, sm, fmds[i], true);
|
attachField(manager, toAttach, sm, fmds[i], true);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1922,9 +1922,11 @@ public class ClassMetaData
|
||||||
* the same name.
|
* the same name.
|
||||||
*/
|
*/
|
||||||
public synchronized FetchGroup addFetchGroup(String 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);
|
FetchGroup fg = (FetchGroup) _fgs.get(name);
|
||||||
if (fg == null) {
|
if (fg == null) {
|
||||||
fg = newFetchGroup(name);
|
fg = new FetchGroup(this, name);
|
||||||
_fgs.put(name, fg);
|
_fgs.put(name, fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1933,33 +1935,19 @@ public class ClassMetaData
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a named fecth group. If not available in this receiver then looks
|
* Gets a named fecth group. If not available in this receiver then looks
|
||||||
* up the inheritence hierarchy. Creates if it does not exist and
|
* up the inheritence hierarchy.
|
||||||
* <code>mustBe</code> is false.
|
|
||||||
*
|
*
|
||||||
* @param name name of a fetch group.
|
* @param name name of a fetch group.
|
||||||
* @param mustBe if true then the named group must exist in this receiver
|
* @return an existing fecth group of the given name if known to this
|
||||||
* or any of its persistent super classes.
|
* receiver or any of its superclasses. Otherwise null.
|
||||||
* @return an existing or newly created fecth group of the given name.
|
|
||||||
*/
|
*/
|
||||||
public synchronized FetchGroup getFetchGroup(String name, boolean mustBe) {
|
public synchronized FetchGroup getFetchGroup(String name) {
|
||||||
FetchGroup fg = (FetchGroup) _fgs.get(name);
|
FetchGroup fg = (FetchGroup) _fgs.get(name);
|
||||||
if (fg == null) {
|
if (fg == null) {
|
||||||
ClassMetaData scm = getPCSuperclassMetaData();
|
ClassMetaData scm = getPCSuperclassMetaData();
|
||||||
if (scm != null)
|
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;
|
return fg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2006 The Apache Software Foundation.
|
* Copyright 2006 The Apache Software Foundation.
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -28,39 +25,31 @@ import java.util.Map;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.openjpa.lib.meta.SourceTracker;
|
import org.apache.openjpa.lib.meta.SourceTracker;
|
||||||
import org.apache.openjpa.lib.util.Localizer;
|
import org.apache.openjpa.lib.util.Localizer;
|
||||||
import org.apache.openjpa.util.MetaDataException;
|
import org.apache.openjpa.util.UserException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Captures fetch group metadata.
|
* Captures fetch group metadata.
|
||||||
*/
|
*/
|
||||||
public class FetchGroup
|
public class FetchGroup implements SourceTracker {
|
||||||
implements SourceTracker {
|
|
||||||
|
|
||||||
private final String _name;
|
private final String _name;
|
||||||
private final ClassMetaData _declaringClass;
|
private final ClassMetaData _declaringClass;
|
||||||
private List _includes;
|
private List _includes;
|
||||||
private Map _depths;
|
private Map _depths;
|
||||||
|
private boolean _postLoad;
|
||||||
public static final int DEFAULT_RECURSION_DEPTH = 1;
|
public static final int DEFAULT_RECURSION_DEPTH = 1;
|
||||||
private static String DEFAULT_GROUP_NAME = "default";
|
private static final Localizer _loc =
|
||||||
|
Localizer.forPackage(FetchGroup.class);
|
||||||
private static final Localizer _loc = Localizer.forPackage
|
|
||||||
(FetchGroup.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supply immutable name.
|
* Supply immutable name.
|
||||||
*
|
*
|
||||||
* @param name must not by null or empty.
|
* @param must not by null or empty.
|
||||||
*/
|
*/
|
||||||
FetchGroup(ClassMetaData cm, String name) {
|
FetchGroup(ClassMetaData cm, String name) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
if (cm == null)
|
|
||||||
throw new MetaDataException(_loc.get("null-class-fg", name));
|
|
||||||
if (StringUtils.isEmpty(name))
|
if (StringUtils.isEmpty(name))
|
||||||
throw new MetaDataException(_loc.get("invalid-fg-name", cm,
|
throw new UserException(_loc.get("invalid-fg-name", cm, name));
|
||||||
name));
|
|
||||||
|
|
||||||
_name = name;
|
_name = name;
|
||||||
_declaringClass = cm;
|
_declaringClass = cm;
|
||||||
}
|
}
|
||||||
|
@ -77,12 +66,11 @@ public class FetchGroup
|
||||||
*/
|
*/
|
||||||
public void addInclude(FetchGroup fg) {
|
public void addInclude(FetchGroup fg) {
|
||||||
if (fg == this)
|
if (fg == this)
|
||||||
throw new MetaDataException(_loc.get("self-include-fg", this));
|
throw new UserException(_loc.get("self-include-fg", this));
|
||||||
if (fg == null)
|
if (fg == null)
|
||||||
throw new MetaDataException(_loc.get("null-include-fg", this));
|
throw new UserException(_loc.get("null-include-fg", this));
|
||||||
if (fg.includes(this, true))
|
if (fg.includes(this, true))
|
||||||
throw new MetaDataException(_loc.get("cyclic-fg", this, fg));
|
throw new UserException(_loc.get("cyclic-fg", this, fg));
|
||||||
|
|
||||||
if (_includes == null)
|
if (_includes == null)
|
||||||
_includes = new ArrayList();
|
_includes = new ArrayList();
|
||||||
_includes.add(fg);
|
_includes.add(fg);
|
||||||
|
@ -94,18 +82,17 @@ public class FetchGroup
|
||||||
* @param fg
|
* @param fg
|
||||||
* @param recurse if true then recursively checks within the included
|
* @param recurse if true then recursively checks within the included
|
||||||
* fecth groups. Otherwise just checks within direct includes.
|
* fecth groups. Otherwise just checks within direct includes.
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean includes(FetchGroup fg, boolean recurse) {
|
public boolean includes(FetchGroup fg, boolean recurse) {
|
||||||
if (_includes == null)
|
if (_includes == null)
|
||||||
return false;
|
return false;
|
||||||
if (_includes.contains(fg))
|
if (_includes.contains(fg))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (recurse)
|
if (recurse)
|
||||||
for (Iterator i = _includes.iterator(); i.hasNext();)
|
for (Iterator i = _includes.iterator(); i.hasNext();)
|
||||||
if (((FetchGroup) i.next()).includes(fg, true))
|
if (((FetchGroup) i.next()).includes(fg, true))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,12 +104,10 @@ public class FetchGroup
|
||||||
*/
|
*/
|
||||||
public void setDepthFor(FieldMetaData fm, int depth) {
|
public void setDepthFor(FieldMetaData fm, int depth) {
|
||||||
if (depth < -1)
|
if (depth < -1)
|
||||||
throw new MetaDataException(_loc.get("invalid-fetch-depth",
|
throw new UserException(_loc.get("invalid-fetch-depth",
|
||||||
_name, fm, new Integer(depth)));
|
_name, fm, new Integer(depth)));
|
||||||
|
|
||||||
if (_depths == null)
|
if (_depths == null)
|
||||||
_depths = new HashMap();
|
_depths = new HashMap();
|
||||||
|
|
||||||
_depths.put(fm, new Integer(depth));
|
_depths.put(fm, new Integer(depth));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,31 +120,16 @@ public class FetchGroup
|
||||||
public int getDepthFor(FieldMetaData fm) {
|
public int getDepthFor(FieldMetaData fm) {
|
||||||
if (_depths == null || !_depths.containsKey(fm))
|
if (_depths == null || !_depths.containsKey(fm))
|
||||||
return DEFAULT_RECURSION_DEPTH;
|
return DEFAULT_RECURSION_DEPTH;
|
||||||
|
|
||||||
return ((Integer) _depths.get(fm)).intValue();
|
return ((Integer) _depths.get(fm)).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the name for default group.
|
public boolean isPostLoad () {
|
||||||
* It is expected to be set only once by a compliant implementation.
|
return _postLoad;
|
||||||
* If multiple attempts are made to set the <em>default</em> 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setPostLoad (boolean flag) {
|
||||||
* Get the name in which <em>default</em> fetch group is known.
|
_postLoad = flag;
|
||||||
*
|
|
||||||
* @return name of the default group. Can be null, if not set.
|
|
||||||
*/
|
|
||||||
public static final String getDefaultGroupName() {
|
|
||||||
return DEFAULT_GROUP_NAME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,7 +141,6 @@ public class FetchGroup
|
||||||
return _name.equals(that._name)
|
return _name.equals(that._name)
|
||||||
&& _declaringClass.equals(that._declaringClass);
|
&& _declaringClass.equals(that._declaringClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +155,6 @@ public class FetchGroup
|
||||||
/////////////////
|
/////////////////
|
||||||
// SourceTracker
|
// SourceTracker
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|
||||||
public File getSourceFile() {
|
public File getSourceFile() {
|
||||||
return _declaringClass.getSourceFile();
|
return _declaringClass.getSourceFile();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.apache.commons.collections.comparators.ComparatorChain;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||||
import org.apache.openjpa.enhance.PersistenceCapable;
|
import org.apache.openjpa.enhance.PersistenceCapable;
|
||||||
|
import org.apache.openjpa.kernel.FetchConfiguration;
|
||||||
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
||||||
import org.apache.openjpa.kernel.StoreContext;
|
import org.apache.openjpa.kernel.StoreContext;
|
||||||
import org.apache.openjpa.lib.conf.Configurations;
|
import org.apache.openjpa.lib.conf.Configurations;
|
||||||
|
@ -849,13 +850,13 @@ public class FieldMetaData
|
||||||
*/
|
*/
|
||||||
public void addFetchGroup(String fg) {
|
public void addFetchGroup(String fg) {
|
||||||
if (StringUtils.isEmpty(fg))
|
if (StringUtils.isEmpty(fg))
|
||||||
return;
|
throw new MetaDataException(_loc.get("bad-fg", fg));
|
||||||
if (getDeclaringMetaData().getFetchGroup(fg, false) == null)
|
if (getDeclaringMetaData().getFetchGroup(fg) == null)
|
||||||
throw new MetaDataException(_loc.get("unknown-fg", fg));
|
throw new MetaDataException(_loc.get("unknown-fg", fg));
|
||||||
if (_fgs == null)
|
if (_fgs == null)
|
||||||
_fgs = new HashSet();
|
_fgs = new HashSet();
|
||||||
_fgs.add(fg);
|
_fgs.add(fg);
|
||||||
if (fg.equals(FetchGroup.getDefaultGroupName()))
|
if (fg.equals(FetchConfiguration.FETCH_GROUP_DEFAULT))
|
||||||
setInDefaultFetchGroup(true);
|
setInDefaultFetchGroup(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -863,7 +864,7 @@ public class FieldMetaData
|
||||||
if (_fgs == null)
|
if (_fgs == null)
|
||||||
return;
|
return;
|
||||||
_fgs.remove(fg);
|
_fgs.remove(fg);
|
||||||
if (fg != null && fg.equals(FetchGroup.getDefaultGroupName()))
|
if (FetchConfiguration.FETCH_GROUP_DEFAULT.equals(fg))
|
||||||
setInDefaultFetchGroup(false);
|
setInDefaultFetchGroup(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Iterator;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.openjpa.enhance.PersistenceCapable;
|
import org.apache.openjpa.enhance.PersistenceCapable;
|
||||||
|
import org.apache.openjpa.kernel.FetchConfiguration;
|
||||||
import org.apache.openjpa.kernel.FetchState;
|
import org.apache.openjpa.kernel.FetchState;
|
||||||
import org.apache.openjpa.kernel.LockManager;
|
import org.apache.openjpa.kernel.LockManager;
|
||||||
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
||||||
|
@ -90,18 +91,18 @@ public class ImplHelper {
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public static Collection loadAll(Collection sms, StoreManager store,
|
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;
|
Collection failed = null;
|
||||||
OpenJPAStateManager sm;
|
OpenJPAStateManager sm;
|
||||||
LockManager lm;
|
LockManager lm;
|
||||||
for (Iterator itr = sms.iterator(); itr.hasNext();) {
|
for (Iterator itr = sms.iterator(); itr.hasNext();) {
|
||||||
sm = (OpenJPAStateManager) itr.next();
|
sm = (OpenJPAStateManager) itr.next();
|
||||||
|
FetchState fetchState = fetch.newFetchState();
|
||||||
if (sm.getManagedInstance() == null) {
|
if (sm.getManagedInstance() == null) {
|
||||||
if (!store.initialize(sm, state, fetchState, context))
|
if (!store.initialize(sm, state, fetchState, context))
|
||||||
failed = addFailedId(sm, failed);
|
failed = addFailedId(sm, failed);
|
||||||
} else if (load != StoreManager.FORCE_LOAD_NONE
|
} else if (load != StoreManager.FORCE_LOAD_NONE
|
||||||
|| sm.getPCState() == PCState.HOLLOW) {
|
|| sm.getPCState() == PCState.HOLLOW) {
|
||||||
|
|
||||||
lm = sm.getContext().getLockManager();
|
lm = sm.getContext().getLockManager();
|
||||||
if (!store.load(sm, sm.getUnloaded(fetchState),
|
if (!store.load(sm, sm.getUnloaded(fetchState),
|
||||||
fetchState, lm.getLockLevel(sm), context))
|
fetchState, lm.getLockLevel(sm), context))
|
||||||
|
|
Loading…
Reference in New Issue