Author: awhite Date: Wed Aug 2 15:23:32 2006 New Revision: 428177 URL: http://svn.apache.org/viewvc?rev=428177&view=rev Log: Allow null load-fetch-group. Allow a DFG field to have a different load-fetch-group. Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=428177&r1=428176&r2=428177&view=diff ============================================================================== --- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original) +++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Wed Aug 2 15:23:32 2006 @@ -2751,68 +2751,58 @@ return ret; } - protected void loadField(int field, int lockLevel, boolean forWrite, - boolean fgs) { - loadField (field, lockLevel, forWrite, fgs, null); - } - /** * Load the given field's fetch group; the field itself may already be * loaded if it is being set by the user. */ protected void loadField(int field, int lockLevel, boolean forWrite, - boolean fgs, FetchConfiguration fetch) { - if (fetch == null) - fetch = _broker.getFetchConfiguration(); - boolean isLoadFetchGroupAdded = false; + boolean fgs) { + FetchConfiguration fetch = _broker.getFetchConfiguration(); FieldMetaData fmd = _meta.getField(field); BitSet fields = null; + // if this is a dfg field or we need to load our dfg, do so - if (fmd.isInDefaultFetchGroup() - || (fgs && (_flags & FLAG_LOADED) == 0)) + if (fgs && (_flags & FLAG_LOADED) == 0) fields = getUnloadedInternal(fetch, LOAD_FGS, null); - // if not a dfg field, use first custom fetch group as load group - //### need to use metadata load-fetch-group - if (!fmd.isInDefaultFetchGroup()) { - String lfg = fmd.getLoadFetchGroup(); - if (lfg != null) { - FieldMetaData[] fmds = _meta.getFields(); - for (int i = 0; i < fmds.length; i++) { - if (!_loaded.get(i) && (i == field - || fmds[i].isInFetchGroup(lfg))) { - if (fields == null) - fields = new BitSet(fmds.length); - fields.set(i); - } + // check for load fetch group + String lfg = fmd.getLoadFetchGroup(); + boolean lfgAdded = false; + if (lfg != null) { + FieldMetaData[] fmds = _meta.getFields(); + for (int i = 0; i < fmds.length; i++) { + if (!_loaded.get(i) && (i == field + || fmds[i].isInFetchGroup(lfg))) { + if (fields == null) + fields = new BitSet(fmds.length); + fields.set(i); } - // relation field is loaded with the load-fetch-group - // but this addition must be reverted once the load is over - if (isRelation(fmd) && !fetch.hasFetchGroup(lfg)) { - fetch.addFetchGroup(fmd.getLoadFetchGroup()); - isLoadFetchGroupAdded = true; - } - } else if (!_loaded.get(fmd.getIndex())) { - if (fields == null) - fields = new BitSet(); - fields.set(fmd.getIndex()); } + + // relation field is loaded with the load-fetch-group + // but this addition must be reverted once the load is over + if (!fetch.hasFetchGroup(lfg)) { + fetch.addFetchGroup(lfg); + lfgAdded = true; + } + } else if (fmd.isInDefaultFetchGroup() && fields == null) { + // no load group but dfg: add dfg fields if we haven't already + fields = getUnloadedInternal(fetch, LOAD_FGS, null); + } else if (!_loaded.get(fmd.getIndex())) { + // no load group or dfg: load individual field + if (fields == null) + fields = new BitSet(); + fields.set(fmd.getIndex()); } // 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, fetch, lockLevel, null, forWrite); - - // remove the load fetch group - if (isLoadFetchGroupAdded) - fetch.removeFetchGroup(fmd.getLoadFetchGroup()); - } - - private static boolean isRelation(FieldMetaData fm) { - return fm.isDeclaredTypePC() - || fm.getElement().isDeclaredTypePC() - || fm.getKey().isDeclaredTypePC(); + // takes care of things like loading version info and setting PC flags + try { + loadFields(fields, fetch, lockLevel, null, forWrite); + } finally { + if (lfgAdded) + fetch.removeFetchGroup(lfg); + } } /** Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java?rev=428177&r1=428176&r2=428177&view=diff ============================================================================== --- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java (original) +++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java Wed Aug 2 15:23:32 2006 @@ -575,16 +575,22 @@ } /** - * Gets the fetch group that is to be loaded when this receiver is loaded. - * - * @return name of the load fetch group. Can be null, if not explicitly - * set. + * The fetch group that is to be loaded when this receiver is loaded, or + * null if none set. */ public String getLoadFetchGroup () { return _lfg; } /** + * The fetch group that is to be loaded when this receiver is loaded, or + * null if none set. + */ + public void setLoadFetchGroup (String lfg) { + _lfg = lfg; + } + + /** * Whether this field is in the given fetch group. */ public boolean isInFetchGroup(String fg) { @@ -620,12 +626,6 @@ || (!in && _fgSet != null && _fgSet.remove(fg))) _fgs = null; } - - public void setLoadFetchGroup (String lfg) { - if (StringUtils.isEmpty(lfg)) - throw new MetaDataException(_loc.get("empty-fg-name"),this); - _lfg = lfg; - } /** * How the data store should treat null values for this field: @@ -1669,6 +1669,8 @@ } if (_fgSet == null && field._fgSet != null) _fgSet = new HashSet(field._fgSet); + if (_lfg == null) + _lfg = field.getLoadFetchGroup(); if (_lrs == null) _lrs = (field.isLRS()) ? Boolean.TRUE : Boolean.FALSE; if (_valStrategy == -1) Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java?rev=428177&r1=428176&r2=428177&view=diff ============================================================================== --- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java (original) +++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/StoreFacadeTypeRegistry.java Wed Aug 2 15:23:32 2006 @@ -2,6 +2,7 @@ import java.util.Map; +import org.apache.openjpa.kernel.StoreManager; import org.apache.openjpa.lib.util.concurrent.ConcurrentHashMap; /** @@ -37,21 +38,24 @@ * @param implType the registered implementor */ public Class getImplementation(Class facadeType, Class storeType) { - Object key = (storeType == null) ? (Object)facadeType - : new Key(facadeType, storeType); - Class c = (Class) _impls.get(key); - // if no store-specific type, see if there is a generic avaialble - if (c == null && storeType != null) - c = (Class) _impls.get(facadeType); - return c; + // traverse store type hierarchy to store manager to find most specific + // store avaialble + Class impl; + for (; storeType != null && storeType != StoreManager.class; + storeType = storeType.getSuperclass()) { + impl = (Class) _impls.get(new Key(facadeType, storeType)); + if (impl != null) + return impl; + } + return (Class) _impls.get(facadeType); } /** * Lookup key for facade+store hash. */ private static class Key { - private final Class _facadeType; - private final Class _storeType; + public final Class _facadeType; + public final Class _storeType; public Key(Class facadeType, Class storeType) { _facadeType = facadeType;