You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by jr...@apache.org on 2008/09/30 21:42:11 UTC

svn commit: r700563 [2/3] - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbedded.java

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=700563&r1=700562&r2=700563&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Tue Sep 30 12:42:11 2008
@@ -1,3258 +1,3259 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.kernel;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutput;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-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.Iterator;
-import java.util.TimeZone;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.enhance.DynamicPersistenceCapable;
-import org.apache.openjpa.enhance.FieldManager;
-import org.apache.openjpa.enhance.ManagedInstanceProvider;
-import org.apache.openjpa.enhance.PCRegistry;
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.enhance.RedefinitionHelper;
-import org.apache.openjpa.enhance.StateManager;
-import org.apache.openjpa.event.LifecycleEvent;
-import org.apache.openjpa.event.LifecycleEventManager;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FetchGroup;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.meta.UpdateStrategies;
-import org.apache.openjpa.meta.ValueMetaData;
-import org.apache.openjpa.meta.ValueStrategies;
-import org.apache.openjpa.util.ApplicationIds;
-import org.apache.openjpa.util.Exceptions;
-import org.apache.openjpa.util.ImplHelper;
-import org.apache.openjpa.util.InternalException;
-import org.apache.openjpa.util.InvalidStateException;
-import org.apache.openjpa.util.ObjectNotFoundException;
-import org.apache.openjpa.util.OpenJPAId;
-import org.apache.openjpa.util.ProxyManager;
-import org.apache.openjpa.util.RuntimeExceptionTranslator;
-import org.apache.openjpa.util.UserException;
-import serp.util.Numbers;
-
-/**
- * Implementation of the {@link OpenJPAStateManager} interface for use
- * with this runtime. Each state manager manages the state of a single
- * persistence capable instance. The state manager is also responsible for
- * all communications about the instance to the {@link StoreManager}.
- *  The state manager uses the State pattern in both its interaction with
- * the governed instance and its interaction with the broker.
- * In its interactions with the persistence capable instance, it uses the
- * {@link FieldManager} interface. Similarly, when interacting with the
- * broker, it uses the {@link PCState} singleton that represents
- * the current lifecycle state of the instance.
- *
- * @author Abe White
- */
-public class StateManagerImpl
-    implements OpenJPAStateManager, Serializable {
-
-    public static final int LOAD_FGS = 0;
-    public static final int LOAD_ALL = 1;
-    public static final int LOAD_SERIALIZE = 2;
-
-    private static final int FLAG_SAVE = 2 << 0;
-    private static final int FLAG_DEREF = 2 << 1;
-    private static final int FLAG_LOADED = 2 << 2;
-    private static final int FLAG_READ_LOCKED = 2 << 3;
-    private static final int FLAG_WRITE_LOCKED = 2 << 4;
-    private static final int FLAG_OID_ASSIGNED = 2 << 5;
-    private static final int FLAG_LOADING = 2 << 6;
-    private static final int FLAG_PRE_DELETING = 2 << 7;
-    private static final int FLAG_FLUSHED = 2 << 8;
-    private static final int FLAG_PRE_FLUSHED = 2 << 9;
-    private static final int FLAG_FLUSHED_DIRTY = 2 << 10;
-    private static final int FLAG_IMPL_CACHE = 2 << 11;
-    private static final int FLAG_INVERSES = 2 << 12;
-    private static final int FLAG_NO_UNPROXY = 2 << 13;
-    private static final int FLAG_VERSION_CHECK = 2 << 14;
-    private static final int FLAG_VERSION_UPDATE = 2 << 15;
-    private static final int FLAG_DETACHING = 2 << 16;
-
-    private static final Localizer _loc = Localizer.forPackage
-        (StateManagerImpl.class);
-
-    // information about the instance
-    private transient PersistenceCapable _pc = null;
-    private transient ClassMetaData _meta = null;
-    private BitSet _loaded = null;
-    private BitSet _dirty = null;
-    private BitSet _flush = null;
-    private int _flags = 0;
-
-    // id is the state manager identity; oid is the persistent identity.  oid
-    // may be null for embedded and transient-transactional objects or new
-    // instances that haven't been assigned an oid.  id is reassigned to oid
-    // on successful oid assignment (or flush completion if assignment is
-    // during flush)
-    private Object _id = null;
-    private Object _oid = null;
-
-    // the managing persistence manager and lifecycle state
-    private transient BrokerImpl _broker; // this is serialized specially
-    private PCState _state = PCState.TRANSIENT;
-
-    // the current and last loaded version indicators, and the lock object
-    private Object _version = null;
-    private Object _loadVersion = null;
-    private Object _lock = null;
-    private int _readLockLevel = -1;
-    private int _writeLockLevel = -1;
-
-    // delegates when providing/replacing instance data
-    private SingleFieldManager _single = null;
-    private SaveFieldManager _saved = null;
-    private FieldManager _fm = null;
-
-    // impldata; field impldata and intermediate data share the same array
-    private Object _impl = null;
-    private Object[] _fieldImpl = null;
-
-    // information about the owner of this instance, if it is embedded
-    private StateManagerImpl _owner = null;
-    private int _ownerIndex = -1;
-
-    /**
-     * Constructor; supply id, type metadata, and owning persistence manager.
-     */
-    protected StateManagerImpl(Object id, ClassMetaData meta, 
-        BrokerImpl broker) {
-        _id = id;
-        _meta = meta;
-        _broker = broker;
-        _single = new SingleFieldManager(this, broker);
-
-        if (_meta.getIdentityType() == ClassMetaData.ID_UNKNOWN)
-            throw new UserException(_loc.get("meta-unknownid", _meta));
-    }
-
-    /**
-     * Set the owning state and field if this is an embedded instance.
-     */
-    void setOwner(StateManagerImpl owner, ValueMetaData ownerMeta) {
-        _owner = owner;
-        _ownerIndex = ownerMeta.getFieldMetaData().getIndex();
-    }
-
-    /**
-     * Whether this state manager is in the middle of a load.
-     */
-    boolean isLoading() {
-        return (_flags & FLAG_LOADING) > 0;
-    }
-
-    /**
-     * Whether this state manager is in the middle of a load initiated
-     * by outside code; for any internal methods that cause loading, the
-     * loading flag is set automatically.
-     */
-    void setLoading(boolean loading) {
-        if (loading)
-            _flags |= FLAG_LOADING;
-        else
-            _flags &= ~FLAG_LOADING;
-    }
-
-    /**
-     * Set or reset the lifecycle state of the managed instance. If the
-     * transactional state of the instance changes, it will be enlisted/
-     * delisted from the current transaction as necessary. The given
-     * state will be initialized after being set. If the given state
-     * is the same as the current state, this method will have no effect.
-     */
-    private void setPCState(PCState state) {
-        if (_state == state)
-            return;
-
-        lock();
-        try {
-            // notify the store manager that we're changing states; can veto
-            _broker.getStoreManager().beforeStateChange(this, _state, state);
-
-            // replace state
-            boolean wasDeleted = _state.isDeleted();
-            boolean wasDirty = _state.isDirty();
-            boolean wasPending = _state.isPendingTransactional();
-            _state = state;
-
-            // enlist/delist from transaction
-            if (_state.isTransactional()) {
-                _broker.addToTransaction(this);
-                if (_state.isDeleted() != wasDeleted)
-                    _broker.setDirty(this, !wasDirty || isFlushed());
-                else if (_state.isDirty() && !wasDirty)
-                    _broker.setDirty(this, true);
-            } else if (!wasPending && _state.isPendingTransactional())
-                _broker.addToPendingTransaction(this);
-            else if (wasPending && !_state.isPendingTransactional())
-                _broker.removeFromPendingTransaction(this);
-            else
-                _broker.removeFromTransaction(this);
-
-            // initialize
-            _state.initialize(this);
-            if (_state.isDeleted() && !wasDeleted)
-                fireLifecycleEvent(LifecycleEvent.AFTER_DELETE);
-        } finally {
-            unlock();
-        }
-    }
-
-    //////////////////////////////////////
-    // OpenJPAStateManager implementation
-    //////////////////////////////////////
-
-    public void initialize(Class cls, PCState state) {
-        // check to see if our current object id instance is the
-        // correct id type for the specified class; this is for cases
-        // when we have an application id hierarchy and we had set the
-        // metadata to a superclass id -- the subclass' id may be a
-        // different class, so we need to reset it
-        if (_meta.getDescribedType() != cls) {
-            ClassMetaData sub = _meta.getRepository().getMetaData
-                (cls, _broker.getClassLoader(), true);
-            if (_oid != null) {
-                if (_meta.getIdentityType() == ClassMetaData.ID_DATASTORE)
-                    _oid = _broker.getStoreManager().copyDataStoreId(_oid,
-                        sub);
-                else if (_meta.isOpenJPAIdentity())
-                    _oid = ApplicationIds.copy(_oid, sub);
-                else if (sub.getObjectIdType() != _meta.getObjectIdType()) {
-                    Object[] pkFields = ApplicationIds.toPKValues(_oid, _meta);
-                    _oid = ApplicationIds.fromPKValues(pkFields, sub);
-                }
-            }
-            _meta = sub;
-        }
-
-        PersistenceCapable inst = PCRegistry.newInstance(cls, this, _oid, true);
-        if (inst == null) {
-            // the instance was null: check to see if the instance is
-            // abstract (as can sometimes be the case when the
-            // class discriminator strategy is not configured correctly)
-            if (Modifier.isAbstract(cls.getModifiers()))
-                throw new UserException(_loc.get("instantiate-abstract",
-                    cls.getName(), _oid));
-            throw new InternalException();
-        }
-
-        initialize(inst, state);
-    }
-
-    /**
-     * Initialize with the given instance and state.
-     */
-    protected void initialize(PersistenceCapable pc, PCState state) {
-        if (pc == null)
-            throw new UserException(_loc.get("init-null-pc", _meta));
-        if (pc.pcGetStateManager() != null && pc.pcGetStateManager() != this)
-            throw new UserException(_loc.get("init-sm-pc",
-                Exceptions.toString(pc))).setFailedObject(pc);
-        pc.pcReplaceStateManager(this);
-
-        FieldMetaData[] fmds = _meta.getFields();
-        _loaded = new BitSet(fmds.length);
-        _flush = new BitSet(fmds.length);
-        _dirty = new BitSet(fmds.length);
-
-        for (int i = 0; i < fmds.length; i++) {
-            // mark primary key and non-persistent fields as loaded
-            if (fmds[i].isPrimaryKey()
-                || fmds[i].getManagement() != fmds[i].MANAGE_PERSISTENT)
-                _loaded.set(i);
-
-            // record whether there are any managed inverse fields
-            if (_broker.getInverseManager() != null
-                && fmds[i].getInverseMetaDatas().length > 0)
-                _flags |= FLAG_INVERSES;
-        }
-
-        pc.pcSetDetachedState(null);
-        _pc = pc;
-
-        if (_oid instanceof OpenJPAId)
-            ((OpenJPAId) _oid).setManagedInstanceType(_meta.getDescribedType());
-
-        // initialize our state and add ourselves to the broker's cache
-        setPCState(state);
-        if (_broker.getStateManagerImplById(getObjectId(), false) == null) {
-        	_broker.setStateManager(_id, this, BrokerImpl.STATUS_INIT);
-        }
-        if (state == PCState.PNEW)
-            fireLifecycleEvent(LifecycleEvent.AFTER_PERSIST);
-
-        // if this is a non-tracking PC, add a hard ref to the appropriate data
-        // sets and give it an opportunity to make a state snapshot.
-        if (!isIntercepting()) {
-            saveFields(true);
-            if (!isNew())
-                RedefinitionHelper.assignLazyLoadProxies(this);
-        }
-    }
-
-    /**
-     * Whether or not data access in this instance is intercepted. This differs
-     * from {@link ClassMetaData#isIntercepting()} in that it checks for
-     * property access + subclassing in addition to the redefinition /
-     * enhancement checks.
-     *
-     * @since 1.0.0
-     */
-    public boolean isIntercepting() {
-        if (getMetaData().isIntercepting())
-            return true;
-        if (getMetaData().getAccessType() != ClassMetaData.ACCESS_FIELD
-            && _pc instanceof DynamicPersistenceCapable)
-            return true;
-
-        return false;
-    }
-
-    /**
-     * Fire the given lifecycle event to all listeners.
-     */
-    private boolean fireLifecycleEvent(int type) {
-        return _broker.fireLifecycleEvent(getManagedInstance(), null,
-            _meta, type);
-    }
-
-    public void load(FetchConfiguration fetch) {
-        load(fetch, LOAD_FGS, null, null, false);
-    }
-
-    /**
-     * Load the state of this instance based on the given fetch configuration
-     * and load mode. Return true if any data was loaded, false otherwise.
-     */
-    protected boolean load(FetchConfiguration fetch, int loadMode,
-        BitSet exclude, Object sdata, boolean forWrite) {
-        if (!forWrite && (!isPersistent() || isNew() || isDeleted()))
-            return false;
-
-        // if any fields being loaded, do state transitions for read
-        BitSet fields = getUnloadedInternal(fetch, loadMode, exclude);
-        boolean active = _broker.isActive();
-        if (!forWrite && fields != null)
-            beforeRead(-1);
-
-        // call load even if no fields are being loaded, because it takes
-        // care of checking if the DFG is loaded, making sure version info
-        // is loaded, etc
-        int lockLevel = calculateLockLevel(active, forWrite, fetch);
-        boolean ret = loadFields(fields, fetch, lockLevel, sdata);
-        obtainLocks(active, forWrite, lockLevel, fetch, sdata);
-        return ret;
-    }
-
-    public Object getManagedInstance() {
-        if (_pc instanceof ManagedInstanceProvider)
-            return ((ManagedInstanceProvider) _pc).getManagedInstance();
-        else
-            return _pc;
-    }
-
-    public PersistenceCapable getPersistenceCapable() {
-        return _pc;
-    }
-
-    public ClassMetaData getMetaData() {
-        return _meta;
-    }
-
-    public OpenJPAStateManager getOwner() {
-        return _owner;
-    }
-
-    public int getOwnerIndex() {
-        return _ownerIndex;
-    }
-
-    public boolean isEmbedded() {
-        return _owner != null;
-    }
-
-    public boolean isFlushed() {
-        return (_flags & FLAG_FLUSHED) > 0;
-    }
-
-    public boolean isFlushedDirty() {
-        return (_flags & FLAG_FLUSHED_DIRTY) > 0;
-    }
-
-    public BitSet getLoaded() {
-        return _loaded;
-    }
-
-    public BitSet getFlushed() {
-        return _flush;
-    }
-
-    public BitSet getDirty() {
-        return _dirty;
-    }
-
-    public BitSet getUnloaded(FetchConfiguration fetch) {
-        // collect fields to load from data store based on fetch configuration
-        BitSet fields = getUnloadedInternal(fetch, LOAD_FGS, null);
-        return (fields == null) ? new BitSet(0) : fields;
-    }
-
-    /**
-     * Internal version of {@link OpenJPAStateManager#getUnloaded} that avoids
-     * creating an empty bit set by returning null when there are no unloaded
-     * fields.
-     */
-    private BitSet getUnloadedInternal(FetchConfiguration fetch, int mode,
-        BitSet exclude) {
-        if (exclude == StoreContext.EXCLUDE_ALL)
-            return null;
-
-        BitSet fields = null;
-        FieldMetaData[] fmds = _meta.getFields();
-        boolean load;
-        for (int i = 0; i < fmds.length; i++) {
-            if (_loaded.get(i) || (exclude != null && exclude.get(i)))
-                continue;
-
-            switch (mode) {
-                case LOAD_SERIALIZE:
-                    load = !fmds[i].isTransient();
-                    break;
-                case LOAD_FGS:
-                    load = fetch == null || fetch.requiresFetch(fmds[i]) 
-                        != FetchConfiguration.FETCH_NONE;
-                    break;
-                default: // LOAD_ALL
-                    load = true;
-            }
-
-            if (load) {
-                if (fields == null)
-                    fields = new BitSet(fmds.length);
-                fields.set(i);
-            }
-        }
-        return fields;
-    }
-
-    public StoreContext getContext() {
-        return _broker;
-    }
-
-    /**
-     * Managing broker.
-     */
-    BrokerImpl getBroker() {
-        return _broker;
-    }
-
-    public Object getId() {
-        return _id;
-    }
-
-    public Object getObjectId() {
-        StateManagerImpl sm = this;
-        while (sm.getOwner() != null)
-            sm = (StateManagerImpl) sm.getOwner();
-        return sm._oid;
-    }
-
-    public void setObjectId(Object oid) {
-        _oid = oid;
-        if (_pc != null && oid instanceof OpenJPAId)
-            ((OpenJPAId) oid).setManagedInstanceType(_meta.getDescribedType());
-    }
-
-    public boolean assignObjectId(boolean flush) {
-        lock();
-        try {
-            return assignObjectId(flush, false);
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Ask store manager to assign our oid, optionally flushing and
-     * optionally recaching on the new oid.
-     */
-    boolean assignObjectId(boolean flush, boolean preFlushing) {
-        if (_oid != null || isEmbedded() || !isPersistent())
-            return true;
-
-        if (_broker.getStoreManager().assignObjectId(this, preFlushing)) {
-            if (!preFlushing)
-                assertObjectIdAssigned(true);
-        } else if (flush)
-            _broker.flush();
-        else
-            return false;
-        return true;
-    }
-
-    /**
-     * Make sure we were assigned an oid, and perform actions to make it
-     * permanent.
-     *
-     * @param recache whether to recache ourself on the new oid
-     */
-    private void assertObjectIdAssigned(boolean recache) {
-        if (!isNew() || isDeleted() || isProvisional() 
-            || (_flags & FLAG_OID_ASSIGNED) != 0)
-            return;
-        if (_oid == null) {
-            if (_meta.getIdentityType() == ClassMetaData.ID_DATASTORE)
-                throw new InternalException(Exceptions.toString
-                    (getManagedInstance()));
-            _oid = ApplicationIds.create(_pc, _meta);
-        }
-
-        Object orig = _id;
-        _id = _oid;
-        if (recache) {
-            try {
-                _broker.setStateManager(orig, this,
-                    BrokerImpl.STATUS_OID_ASSIGN);
-            } catch (RuntimeException re) {
-                _id = orig;
-                _oid = null;
-                throw re;
-            }
-        }
-        _flags |= FLAG_OID_ASSIGNED;
-    }
-
-    /**
-     * Assign the proper generated value to the given field based on its
-     * value-strategy.
-     */
-    private boolean assignField(int field, boolean preFlushing) {
-        OpenJPAStateManager sm = this;
-        while (sm.isEmbedded())
-            sm = sm.getOwner();
-        if (!sm.isNew() || sm.isFlushed() || sm.isDeleted())
-            return false;
-
-        // special-case oid fields, which require us to look inside the oid
-        // object
-        FieldMetaData fmd = _meta.getField(field);
-        if (fmd.getDeclaredTypeCode() == JavaTypes.OID) {
-            // try to shortcut if possible
-            if (_oid != null || isEmbedded() || !isPersistent())
-                return true;
-
-            // check embedded fields of oid for value strategy + default value
-            FieldMetaData[] pks = fmd.getEmbeddedMetaData().getFields();
-            OpenJPAStateManager oidsm = null;
-            boolean assign = false;
-            for (int i = 0; !assign && i < pks.length; i++) {
-                if (pks[i].getValueStrategy() == ValueStrategies.NONE)
-                    continue;
-                if (oidsm == null)
-                    oidsm = new ObjectIdStateManager(fetchObjectField(field),
-                        this, fmd);
-                assign = oidsm.isDefaultValue(i);
-            }
-            return assign && assignObjectId(!preFlushing, preFlushing);
-        }
-
-        // Just return if there's no value generation strategy
-        if (fmd.getValueStrategy() == ValueStrategies.NONE)
-            return false;
-        
-        // Throw exception if field already has a value assigned.
-        // @GeneratedValue overrides POJO initial values and setter methods
-        if (!fmd.isValueGenerated() && !isDefaultValue(field))
-            throw new InvalidStateException(_loc.get(
-                "existing-value-override-excep", fmd.getFullName(false)));
-
-        // for primary key fields, assign the object id and recache so that
-        // to the user, so it looks like the oid always matches the pk fields
-        if (fmd.isPrimaryKey() && !isEmbedded())
-            return assignObjectId(!preFlushing, preFlushing);
-
-        // for other fields just assign the field or flush if needed
-        if (_broker.getStoreManager().assignField(this, field, preFlushing)) {
-            fmd.setValueGenerated(true);
-            return true;
-        }
-        if (!preFlushing)
-            _broker.flush();
-        return !preFlushing;
-    }
-
-    public Object getLock() {
-        return _lock;
-    }
-
-    public void setLock(Object lock) {
-        _lock = lock;
-    }
-
-    public Object getVersion() {
-        return _version;
-    }
-
-    public void setVersion(Object version) {
-        _loadVersion = version;
-        assignVersionField(version);
-    }
-
-    Object getLoadVersion() {
-        return _loadVersion;
-    }
-
-    public void setNextVersion(Object version) {
-        assignVersionField(version);
-    }
-
-    private void assignVersionField(Object version) {
-        _version = version;
-        FieldMetaData vfield = _meta.getVersionField();
-        if (vfield != null)
-            store(vfield.getIndex(), JavaTypes.convert(version,
-                vfield.getTypeCode()));
-    }
-
-    public PCState getPCState() {
-        return _state;
-    }
-
-    public synchronized Object getImplData() {
-        return _impl;
-    }
-
-    public synchronized Object setImplData(Object data, boolean cacheable) {
-        Object old = _impl;
-        _impl = data;
-        if (cacheable && data != null)
-            _flags |= FLAG_IMPL_CACHE;
-        else
-            _flags &= ~FLAG_IMPL_CACHE;
-        return old;
-    }
-
-    public boolean isImplDataCacheable() {
-        return (_flags & FLAG_IMPL_CACHE) != 0;
-    }
-
-    public Object getImplData(int field) {
-        return getExtraFieldData(field, true);
-    }
-
-    public Object setImplData(int field, Object data) {
-        return setExtraFieldData(field, data, true);
-    }
-
-    public synchronized boolean isImplDataCacheable(int field) {
-        if (_fieldImpl == null || !_loaded.get(field))
-            return false;
-        if (_meta.getField(field).usesImplData() != null)
-            return false;
-        int idx = _meta.getExtraFieldDataIndex(field);
-        return idx != -1 && _fieldImpl[idx] != null;
-    }
-
-    public Object getIntermediate(int field) {
-        return getExtraFieldData(field, false);
-    }
-
-    public void setIntermediate(int field, Object data) {
-        setExtraFieldData(field, data, false);
-    }
-
-    /**
-     * Return the data from the proper index of the extra field data array.
-     */
-    private synchronized Object getExtraFieldData(int field, boolean isLoaded) {
-        // only return the field data if the field is in the right loaded
-        // state; otherwise we might return intermediate for impl data or
-        // vice versa
-        if (_fieldImpl == null || _loaded.get(field) != isLoaded)
-            return null;
-        int idx = _meta.getExtraFieldDataIndex(field);
-        return (idx == -1) ? null : _fieldImpl[idx];
-    }
-
-    /**
-     * Set the data from to proper index of the extra field data array.
-     */
-    private synchronized Object setExtraFieldData(int field, Object data,
-        boolean loaded) {
-        int idx = _meta.getExtraFieldDataIndex(field);
-        if (idx == -1)
-            throw new InternalException(String.valueOf(_meta.getField(field)));
-
-        Object old = (_fieldImpl == null) ? null : _fieldImpl[idx];
-        if (data != null) {
-            // cannot set if field in wrong loaded state
-            if (_loaded.get(field) != loaded)
-                throw new InternalException(String.valueOf(_meta.getField
-                    (field)));
-
-            // set data
-            if (_fieldImpl == null)
-                _fieldImpl = new Object[_meta.getExtraFieldDataLength()];
-            _fieldImpl[idx] = data;
-        } else if (_fieldImpl != null && _loaded.get(field) == loaded)
-            _fieldImpl[idx] = null;
-        return old;
-    }
-
-    public Object fetch(int field) {
-        Object val = fetchField(field, false);
-        return _meta.getField(field).getExternalValue(val, _broker);
-    }
-
-    public Object fetchField(int field, boolean transitions) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (fmd == null)
-            throw new UserException(_loc.get("no-field",
-                String.valueOf(field), getManagedInstance().getClass())).
-                setFailedObject(getManagedInstance());
-
-        // do normal state transitions
-        if (!fmd.isPrimaryKey() && transitions)
-            accessingField(field);
-
-        switch (fmd.getDeclaredTypeCode()) {
-            case JavaTypes.STRING:
-                return fetchStringField(field);
-            case JavaTypes.OBJECT:
-                return fetchObjectField(field);
-            case JavaTypes.BOOLEAN:
-                return (fetchBooleanField(field)) ? Boolean.TRUE
-                    : Boolean.FALSE;
-            case JavaTypes.BYTE:
-                return new Byte(fetchByteField(field));
-            case JavaTypes.CHAR:
-                return new Character(fetchCharField(field));
-            case JavaTypes.DOUBLE:
-                return new Double(fetchDoubleField(field));
-            case JavaTypes.FLOAT:
-                return new Float(fetchFloatField(field));
-            case JavaTypes.INT:
-                return Numbers.valueOf(fetchIntField(field));
-            case JavaTypes.LONG:
-                return Numbers.valueOf(fetchLongField(field));
-            case JavaTypes.SHORT:
-                return new Short(fetchShortField(field));
-            default:
-                return fetchObjectField(field);
-        }
-    }
-
-    public void store(int field, Object val) {
-        val = _meta.getField(field).getFieldValue(val, _broker);
-        storeField(field, val);
-    }
-
-    public void storeField(int field, Object val) {
-        storeField(field, val, this);
-    }
-
-    /**
-     * <p>Checks whether or not <code>_pc</code> is dirty. In the cases where
-     * field tracking is not happening (see below), this method will do a
-     * state comparison to find whether <code>_pc</code> is dirty, and will
-     * update this instance with this information. In the cases where field
-     * tracking is happening, this method is a no-op.</p>
-     *
-     * <p>Fields are tracked for all classes that are run through the OpenJPA
-     * enhancer prior to or during deployment, and all classes (enhanced or
-     * unenhanced) in a Java 6 environment or newer.</p>
-     *
-     * <p>In a Java 5 VM or older:
-     * <br>- instances of unenhanced classes that use
-     * property access and obey the property access limitations are tracked
-     * when the instances are loaded from the database by OpenJPA, and are
-     * not tracked when the instances are created by application code.
-     * <br>- instances of unenhanced classes that use field access are
-     * never tracked.</p>
-     *
-     * @since 1.0.0
-     */
-    public void dirtyCheck() {
-        if (!needsDirtyCheck())
-            return;
-
-        SaveFieldManager saved = getSaveFieldManager();
-        if (saved == null)
-            throw new InternalException(_loc.get("no-saved-fields",
-                getMetaData().getDescribedType().getName()));
-
-        FieldMetaData[] fmds = getMetaData().getFields();
-        for (int i = 0; i < fmds.length; i++) {
-            // pk and version fields cannot be mutated; don't mark them
-            // as such. ##### validate?
-            if (!fmds[i].isPrimaryKey() && !fmds[i].isVersion()
-                && _loaded.get(i)) {
-                if (!saved.isFieldEqual(i, fetch(i))) {
-                    dirty(i);
-                }
-            }
-        }
-    }
-
-    private boolean needsDirtyCheck() {
-        if (isIntercepting())
-            return false;
-        if (isDeleted())
-            return false;
-        if (isNew() && !isFlushed())
-            return false;
-        return true;
-    }
-
-    public Object fetchInitialField(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (_broker.getRestoreState() == RestoreState.RESTORE_NONE
-            && ((_flags & FLAG_INVERSES) == 0
-            || fmd.getInverseMetaDatas().length == 0))
-            throw new InvalidStateException(_loc.get("restore-unset"));
-
-        switch (fmd.getDeclaredTypeCode()) {
-            case JavaTypes.DATE:
-            case JavaTypes.CALENDAR:
-            case JavaTypes.ARRAY:
-            case JavaTypes.COLLECTION:
-            case JavaTypes.MAP:
-            case JavaTypes.OBJECT:
-                // if we're not saving mutable types, throw an exception
-                if (_broker.getRestoreState() != RestoreState.RESTORE_ALL
-                    && ((_flags & FLAG_INVERSES) == 0
-                    || fmd.getInverseMetaDatas().length == 0))
-                    throw new InvalidStateException(_loc.get
-                        ("mutable-restore-unset"));
-        }
-
-        lock();
-        try {
-            if (_saved == null || !_loaded.get(field) || !_dirty.get(field))
-                return fetchField(field, false);
-
-            // if the field is dirty but we never loaded it, we can't restore it
-            if (_saved.getUnloaded().get(field))
-                throw new InvalidStateException(_loc.get("initial-unloaded",
-                    fmd));
-
-            provideField(_saved.getState(), _single, field);
-            return fetchField(_single, fmd);
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Fetch the specified field from the specified field manager, wrapping it
-     * in an object if it's a primitive. A field should be provided to the
-     * field manager before this call is made.
-     */
-    private static Object fetchField(FieldManager fm, FieldMetaData fmd) {
-        int field = fmd.getIndex();
-        switch (fmd.getDeclaredTypeCode()) {
-            case JavaTypes.BOOLEAN:
-                return (fm.fetchBooleanField(field)) ? Boolean.TRUE
-                    : Boolean.FALSE;
-            case JavaTypes.BYTE:
-                return new Byte(fm.fetchByteField(field));
-            case JavaTypes.CHAR:
-                return new Character(fm.fetchCharField(field));
-            case JavaTypes.DOUBLE:
-                return new Double(fm.fetchDoubleField(field));
-            case JavaTypes.FLOAT:
-                return new Float(fm.fetchFloatField(field));
-            case JavaTypes.INT:
-                return Numbers.valueOf(fm.fetchIntField(field));
-            case JavaTypes.LONG:
-                return Numbers.valueOf(fm.fetchLongField(field));
-            case JavaTypes.SHORT:
-                return new Short(fm.fetchShortField(field));
-            case JavaTypes.STRING:
-                return fm.fetchStringField(field);
-            default:
-                return fm.fetchObjectField(field);
-        }
-    }
-
-    public void setRemote(int field, Object value) {
-        lock();
-        try {
-            Boolean stat = dirty(field, Boolean.FALSE, false);
-            storeField(field, value, _single);
-            replaceField(_pc, _single, field);
-            postDirty(stat);
-        } finally {
-            unlock();
-        }
-    }
-
-    ////////////////////////
-    // Lifecycle operations
-    ////////////////////////
-
-    /**
-     * Notification that the object is about to be accessed.
-     *
-     * @param field the field number being read, or -1 if not a single
-     * field read
-     */
-    void beforeRead(int field) {
-        // allow unmediated reads of primary key fields
-        if (field != -1 && _meta.getField(field).isPrimaryKey())
-            return;
-
-        if (_broker.isActive() && !_broker.isTransactionEnding()) {
-            if (_broker.getOptimistic())
-                setPCState(_state.beforeOptimisticRead(this, field));
-            else
-                setPCState(_state.beforeRead(this, field));
-        } else if (_broker.getNontransactionalRead())
-            setPCState(_state.beforeNontransactionalRead(this, field));
-        else
-            throw new InvalidStateException(_loc.get("non-trans-read")).
-                setFailedObject(getManagedInstance());
-    }
-
-    /**
-     * Delegates to the current state.
-     *
-     * @see PCState#beforeFlush
-     */
-    void beforeFlush(int reason, OpCallbacks call) {
-        _state.beforeFlush(this, reason == BrokerImpl.FLUSH_LOGICAL, call);
-    }
-
-    /**
-     * Delegates to the current state.
-     *
-     * @see PCState#flush
-     */
-    void afterFlush(int reason) {
-        // nothing happens when we flush non-persistent states
-        if (!isPersistent())
-            return;
-
-        if (reason != BrokerImpl.FLUSH_ROLLBACK
-            && reason != BrokerImpl.FLUSH_LOGICAL) {
-            // analyze previous state for later
-            boolean wasNew = isNew();
-            boolean wasFlushed = isFlushed();
-            boolean wasDeleted = isDeleted();
-
-            // all dirty fields were flushed
-            _flush.or(_dirty);
-
-            // important to set flushed bit after calling _state.flush so
-            // that the state can tell whether this is the first flush
-            setPCState(_state.flush(this));
-            _flags |= FLAG_FLUSHED;
-            _flags &= ~FLAG_FLUSHED_DIRTY;
-
-            _flags &= ~FLAG_VERSION_CHECK;
-            _flags &= ~FLAG_VERSION_UPDATE;
-
-            // if this was an inc flush during which we had our identity
-            // assigned, tell the broker to cache us under our final oid
-            if (reason == BrokerImpl.FLUSH_INC)
-                assertObjectIdAssigned(true);
-
-            // if this object was stored with preFlush, do post-store callback
-            if ((_flags & FLAG_PRE_FLUSHED) > 0)
-                fireLifecycleEvent(LifecycleEvent.AFTER_STORE);
-
-            // do post-update as needed
-            if (wasNew && !wasFlushed)
-                fireLifecycleEvent(LifecycleEvent.AFTER_PERSIST_PERFORMED);
-            else if (wasDeleted)
-                fireLifecycleEvent(LifecycleEvent.AFTER_DELETE_PERFORMED);
-            else 
-                // updates and new-flushed with changes
-                fireLifecycleEvent(LifecycleEvent.AFTER_UPDATE_PERFORMED);
-        } else if (reason == BrokerImpl.FLUSH_ROLLBACK) {
-            // revert to last loaded version and original oid
-            assignVersionField(_loadVersion);
-            if (isNew() && (_flags & FLAG_OID_ASSIGNED) == 0)
-                _oid = null;
-        }
-        _flags &= ~FLAG_PRE_FLUSHED;
-    }
-
-    /**
-     * Delegates to the current state after checking the value
-     * of the RetainState flag.
-     *
-     * @see PCState#commit
-     * @see PCState#commitRetain
-     */
-    void commit() {
-        // release locks before oid updated
-        releaseLocks();
-
-        // update version and oid information
-        setVersion(_version);
-        _flags &= ~FLAG_FLUSHED;
-        _flags &= ~FLAG_FLUSHED_DIRTY;
-
-        Object orig = _id;
-        assertObjectIdAssigned(false);
-
-        boolean wasNew = isNew() && !isDeleted() && !isProvisional();
-        if (_broker.getRetainState())
-            setPCState(_state.commitRetain(this));
-        else
-            setPCState(_state.commit(this));
-
-        // ask the broker to re-cache us if we were new previously
-        if (wasNew)
-            _broker.setStateManager(orig, this, BrokerImpl.STATUS_COMMIT_NEW);
-    }
-
-    /**
-     * Delegates to the current state after checking the value
-     * of the RetainState flag.
-     *
-     * @see PCState#rollback
-     * @see PCState#rollbackRestore
-     */
-    void rollback() {
-        // release locks
-        releaseLocks();
-        _flags &= ~FLAG_FLUSHED;
-        _flags &= ~FLAG_FLUSHED_DIRTY;
-        afterFlush(BrokerImpl.FLUSH_ROLLBACK);
-
-        if (_broker.getRestoreState() != RestoreState.RESTORE_NONE)
-            setPCState(_state.rollbackRestore(this));
-        else
-            setPCState(_state.rollback(this));
-    }
-
-    /**
-     * Rollback state of the managed instance to the given savepoint.
-     */
-    void rollbackToSavepoint(SavepointFieldManager savepoint) {
-        _state = savepoint.getPCState();
-        BitSet loaded = savepoint.getLoaded();
-        for (int i = 0, len = loaded.length(); i < len; i++) {
-            if (loaded.get(i) && savepoint.restoreField(i)) {
-                provideField(savepoint.getCopy(), savepoint, i);
-                replaceField(_pc, savepoint, i);
-            }
-        }
-        _loaded = loaded;
-        _dirty = savepoint.getDirty();
-        _flush = savepoint.getFlushed();
-        _version = savepoint.getVersion();
-        _loadVersion = savepoint.getLoadVersion();
-    }
-
-    /**
-     * Delegates to the current state.
-     *
-     * @see PCState#persist
-     * @see Broker#persist
-     */
-    void persist() {
-        setPCState(_state.persist(this));
-    }
-
-    /**
-     * Delegates to the current state.
-     *
-     * @see PCState#delete
-     * @see Broker#delete
-     */
-    void delete() {
-        setPCState(_state.delete(this));
-    }
-
-    /**
-     * Delegates to the current state.
-     *
-     * @see PCState#nontransactional
-     * @see Broker#nontransactional
-     */
-    void nontransactional() {
-        setPCState(_state.nontransactional(this));
-    }
-
-    /**
-     * Delegates to the current state.
-     *
-     * @see PCState#transactional
-     * @see Broker#transactional
-     */
-    void transactional() {
-        setPCState(_state.transactional(this));
-    }
-
-    /**
-     * Delegates to the current state.
-     *
-     * @see PCState#nonprovisional
-     */
-    void nonprovisional(boolean logical, OpCallbacks call) {
-        setPCState(_state.nonprovisional(this, logical, call));
-    }
-
-    /**
-     * Delegates to the current state.
-     *
-     * @see PCState#release
-     * @see Broker#release
-     */
-    void release(boolean unproxy) {
-        release(unproxy, false);
-    }
-
-    void release(boolean unproxy, boolean force) {
-        // optimization for detach-in-place special case when fields are
-        // already (un)proxied correctly
-        if (!unproxy)
-            _flags |= FLAG_NO_UNPROXY;
-        try {
-            if (force)
-                setPCState(PCState.TRANSIENT);
-            else
-                setPCState(_state.release(this));
-        } finally {
-            _flags &= ~FLAG_NO_UNPROXY;
-        }
-    }
-
-    /**
-     * Delegates to the current state.
-     *
-     * @see PCState#evict
-     * @see Broker#evict
-     */
-    void evict() {
-        setPCState(_state.evict(this));
-    }
-
-    /**
-     * Gather relations reachable from values using
-     * {@link ValueMetaData#CASCADE_IMMEDIATE}.
-     */
-    void gatherCascadeRefresh(OpCallbacks call) {
-        FieldMetaData[] fmds = _meta.getFields();
-        for (int i = 0; i < fmds.length; i++) {
-            if (!_loaded.get(i))
-                continue;
-
-            if (fmds[i].getCascadeRefresh() == ValueMetaData.CASCADE_IMMEDIATE
-                || fmds[i].getKey().getCascadeRefresh()
-                == ValueMetaData.CASCADE_IMMEDIATE
-                || fmds[i].getElement().getCascadeRefresh()
-                == ValueMetaData.CASCADE_IMMEDIATE) {
-                _single.storeObjectField(i, fetchField(i, false));
-                _single.gatherCascadeRefresh(call);
-                _single.clear();
-            }
-        }
-    }
-
-    public boolean beforeRefresh(boolean refreshAll) {
-        // note: all logic placed here rather than in the states for
-        // optimization; this method public b/c used by remote package
-
-        // nothing to do for non persistent or new unflushed instances
-        if (!isPersistent() || (isNew() && !isFlushed()))
-            return false;
-
-        lock();
-        try {
-            // if dirty need to clear fields
-            if (isDirty()) {
-                clearFields();
-                return true;
-            }
-
-            // if some fields have been loaded but the instance is out of
-            // date or this is part of a refreshAll() and we don't want to
-            // take the extra hit to see if the instance is out of date, clear
-            if (_loaded.length() > 0 && (refreshAll || isEmbedded()
-                || !syncVersion(null))) {
-                Object version = _version;
-                clearFields();
-
-                // if syncVersion just replaced the version, reset it
-                if (!refreshAll && !isEmbedded())
-                    setVersion(version);
-                return true;
-            }
-            return false;
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Perform state transitions after refresh. This method is only
-     * called if {@link #beforeRefresh} returns true.
-     */
-    void afterRefresh() {
-        lock();
-        try {
-            // transition to clean or nontransactional depending on trans status
-            if (!_broker.isActive())
-                setPCState(_state.afterNontransactionalRefresh());
-            else if (_broker.getOptimistic())
-                setPCState(_state.afterOptimisticRefresh());
-            else
-                setPCState(_state.afterRefresh());
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Mark this object as a dereferenced dependent object.
-     */
-    void setDereferencedDependent(boolean deref, boolean notify) {
-        if (!deref && (_flags & FLAG_DEREF) > 0) {
-            if (notify)
-                _broker.removeDereferencedDependent(this);
-            _flags &= ~FLAG_DEREF;
-        } else if (deref && (_flags & FLAG_DEREF) == 0) {
-            _flags |= FLAG_DEREF;
-            if (notify)
-                _broker.addDereferencedDependent(this);
-        }
-    }
-
-    ///////////
-    // Locking
-    ///////////
-
-    /**
-     * Notification that we've been read-locked. Pass in the level at which
-     * we were locked and the level at which we should write lock ourselves
-     * on dirty.
-     */
-    void readLocked(int readLockLevel, int writeLockLevel) {
-        // make sure object is added to transaction so lock will get
-        // cleared on commit/rollback
-        if (readLockLevel != LockLevels.LOCK_NONE)
-            transactional();
-
-        _readLockLevel = readLockLevel;
-        _writeLockLevel = writeLockLevel;
-        _flags |= FLAG_READ_LOCKED;
-        _flags &= ~FLAG_WRITE_LOCKED;
-    }
-
-    /**
-     * Return the lock level to use when loading state.
-     */
-    private int calculateLockLevel(boolean active, boolean forWrite,
-        FetchConfiguration fetch) {
-        if (!active)
-            return LockLevels.LOCK_NONE;
-        if (fetch == null)
-            fetch = _broker.getFetchConfiguration();
-
-        if (_readLockLevel == -1)
-            _readLockLevel = fetch.getReadLockLevel();
-        if (_writeLockLevel == -1)
-            _writeLockLevel = fetch.getWriteLockLevel();
-        return (forWrite) ? _writeLockLevel : _readLockLevel;
-    }
-
-    /**
-     * Make sure we're locked at the given level.
-     */
-    private void obtainLocks(boolean active, boolean forWrite, int lockLevel,
-        FetchConfiguration fetch, Object sdata) {
-        if (!active)
-            return;
-
-        // if we haven't been locked yet, lock now at the given level
-        int flag = (forWrite) ? FLAG_WRITE_LOCKED : FLAG_READ_LOCKED;
-        if ((_flags & flag) == 0) {
-            // make sure object is added to transaction so lock will get
-            // cleared on commit/rollback
-            if (lockLevel != LockLevels.LOCK_NONE)
-                transactional();
-
-            if (fetch == null)
-                fetch = _broker.getFetchConfiguration();
-            _broker.getLockManager().lock(this, lockLevel,
-                fetch.getLockTimeout(), sdata);
-            _flags |= FLAG_READ_LOCKED;
-            _flags |= flag;
-        }
-    }
-
-    /**
-     * Release locks.
-     */
-    private void releaseLocks() {
-        if (_lock != null)
-            _broker.getLockManager().release(this);
-        _readLockLevel = -1;
-        _writeLockLevel = -1;
-        _flags &= ~FLAG_READ_LOCKED;
-        _flags &= ~FLAG_WRITE_LOCKED;
-    }
-
-    ////////////////////////////////////////////
-    // Implementation of StateManager interface
-    ////////////////////////////////////////////
-
-    /**
-     * @return whether or not unloaded fields should be closed.
-     */
-    public boolean serializing() {
-        // if the broker is in the midst of a serialization, then no special
-        // handling should be performed on the instance, and no subsequent
-        // load should happen
-        if (_broker.isSerializing())
-            return false;
-
-        try {
-            if (_meta.isDetachable())
-                return DetachManager.preSerialize(this);
-
-            load(_broker.getFetchConfiguration(), LOAD_SERIALIZE, null, null, 
-                false);
-            return false;
-        } catch (RuntimeException re) {
-            throw translate(re);
-        }
-    }
-
-    public boolean writeDetached(ObjectOutput out)
-        throws IOException {
-        BitSet idxs = new BitSet(_meta.getFields().length);
-        lock();
-        try {
-            boolean detsm = DetachManager.writeDetachedState(this, out, idxs);
-            if (detsm)
-                _flags |= FLAG_DETACHING;
-
-            FieldMetaData[] fmds = _meta.getFields();
-            for (int i = 0; i < fmds.length; i++) {
-                if (fmds[i].isTransient())
-                    continue;
-                provideField(_pc, _single, i);
-                _single.serialize(out, !idxs.get(i));
-                _single.clear();
-            }
-            return true;
-        } catch (RuntimeException re) {
-            throw translate(re);
-        } finally {
-            _flags &= ~FLAG_DETACHING;
-            unlock();
-        }
-    }
-
-    public void proxyDetachedDeserialized(int idx) {
-        // we don't serialize state manager impls
-        throw new InternalException();
-    }
-
-    public boolean isTransactional() {
-        // special case for TCLEAN, which we want to appear non-trans to
-        // internal code, but which publicly should be transactional
-        return _state == PCState.TCLEAN || _state.isTransactional();
-    }
-
-    public boolean isPendingTransactional() {
-        return _state.isPendingTransactional();
-    }
-
-    public boolean isProvisional() {
-        return _state.isProvisional();
-    }
-
-    public boolean isPersistent() {
-        return _state.isPersistent();
-    }
-
-    public boolean isNew() {
-        return _state.isNew();
-    }
-
-    public boolean isDeleted() {
-        return _state.isDeleted();
-    }
-
-    public boolean isDirty() {
-        return _state.isDirty();
-    }
-
-    public boolean isDetached() {
-        return (_flags & FLAG_DETACHING) != 0;
-    }
-
-    public Object getGenericContext() {
-        return _broker;
-    }
-
-    public Object fetchObjectId() {
-        try {
-            assignObjectId(true);
-            if (_oid == null || !_broker.getConfiguration().
-                getCompatibilityInstance().getCopyObjectIds())
-                return _oid;
-
-            if (_meta.getIdentityType() == ClassMetaData.ID_DATASTORE)
-                return _broker.getStoreManager().copyDataStoreId(_oid, _meta);
-            return ApplicationIds.copy(_oid, _meta);
-        } catch (RuntimeException re) {
-            throw translate(re);
-        }
-    }
-
-    public Object getPCPrimaryKey(Object oid, int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        Object pk = ApplicationIds.get(oid, fmd);
-        if (pk == null)
-            return null;
-
-        ClassMetaData relmeta = fmd.getDeclaredTypeMetaData();
-        pk = ApplicationIds.wrap(relmeta, pk);
-        if (relmeta.getIdentityType() == ClassMetaData.ID_DATASTORE
-            && fmd.getObjectIdFieldTypeCode() == JavaTypes.LONG)
-            pk = _broker.getStoreManager().newDataStoreId(pk, relmeta);
-        else if (relmeta.getIdentityType() == ClassMetaData.ID_APPLICATION 
-            && fmd.getObjectIdFieldType() != relmeta.getObjectIdType())
-            pk = ApplicationIds.fromPKValues(new Object[] { pk }, relmeta);
-        return _broker.find(pk, false, null);
-    }
-
-    public byte replaceFlags() {
-        // we always use load required so that we can detect when objects
-        // are touched for locking or making transactional
-        return PersistenceCapable.LOAD_REQUIRED;
-    }
-
-    public StateManager replaceStateManager(StateManager sm) {
-        return sm;
-    }
-
-    public void accessingField(int field) {
-        // possibly change state
-        try {
-            beforeRead(field);
-            beforeAccessField(field);
-        } catch (RuntimeException re) {
-            throw translate(re);
-        }
-    }
-
-    /**
-     * Load the given field before access.
-     */
-    protected void beforeAccessField(int field) {
-        lock();
-        try {
-            boolean active = _broker.isActive();
-            int lockLevel = calculateLockLevel(active, false, null);
-            if (!_loaded.get(field))
-                loadField(field, lockLevel, false, true);
-            else
-                assignField(field, false);
-            obtainLocks(active, false, lockLevel, null, null);
-        } catch (RuntimeException re) {
-            throw translate(re);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void dirty(String field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (fmd == null)
-            throw translate(new UserException(_loc.get("no-field", field,
-                ImplHelper.getManagedInstance(_pc).getClass()))
-                .setFailedObject(getManagedInstance()));
-
-        dirty(fmd.getIndex(), null, true);
-    }
-
-    public void dirty(int field) {
-        dirty(field, null, true);
-    }
-
-    /**
-     * Make the given field dirty.
-     *
-     * @param mutate if null, may be an SCO mutation; if true, is certainly
-     * a mutation (or at least treat as one)
-     * @return {@link Boolean#FALSE} if this instance was already dirty,
-     * <code>null</code> if it was dirty but not since flush, and
-     * {@link Boolean#TRUE} if it was not dirty
-     */
-    private Boolean dirty(int field, Boolean mutate, boolean loadFetchGroup) {
-        boolean locked = false;
-        boolean newFlush = false;
-        boolean clean = false;
-        try {
-            FieldMetaData fmd = _meta.getField(field);
-            if (!isNew() || isFlushed()) {
-                if (fmd.getUpdateStrategy() == UpdateStrategies.RESTRICT)
-                    throw new InvalidStateException(_loc.get
-                        ("update-restrict", fmd));
-                if (fmd.getUpdateStrategy() == UpdateStrategies.IGNORE)
-                    return Boolean.FALSE;
-            }
-
-            if (isEmbedded()) {
-                // notify owner of change
-                _owner.dirty(_ownerIndex, Boolean.TRUE, loadFetchGroup);
-            }
-
-            // is this a direct mutation of an sco field?
-            if (mutate == null) {
-                switch (fmd.getDeclaredTypeCode()) {
-                    case JavaTypes.COLLECTION:
-                    case JavaTypes.MAP:
-                    case JavaTypes.ARRAY:
-                    case JavaTypes.DATE:
-                    case JavaTypes.CALENDAR:
-                    case JavaTypes.OBJECT:
-                        mutate = Boolean.TRUE;
-                        break;
-                    case JavaTypes.PC:
-                        mutate =
-                            (fmd.isEmbedded()) ? Boolean.TRUE : Boolean.FALSE;
-                        break;
-                    default:
-                        mutate = Boolean.FALSE; // not sco
-                }
-            }
-
-            // possibly change state
-            boolean active = _broker.isActive();
-            clean = !_state.isDirty(); // intentional direct access
-
-            // fire event fast before state change.
-            if (clean)
-                fireLifecycleEvent(LifecycleEvent.BEFORE_DIRTY);
-            if (active) {
-                if (_broker.getOptimistic())
-                    setPCState(_state.beforeOptimisticWrite(this, field,
-                        mutate.booleanValue()));
-                else
-                    setPCState(_state.beforeWrite(this, field,
-                        mutate.booleanValue()));
-            } else if (fmd.getManagement() == FieldMetaData.MANAGE_PERSISTENT) {
-                if (isPersistent() && !_broker.getNontransactionalWrite())
-                    throw new InvalidStateException(_loc.get
-                        ("non-trans-write")).setFailedObject
-                        (getManagedInstance());
-
-                setPCState(_state.beforeNontransactionalWrite(this, field,
-                    mutate.booleanValue()));
-            }
-
-            if ((_flags & FLAG_FLUSHED) != 0) {
-                newFlush = (_flags & FLAG_FLUSHED_DIRTY) == 0;
-                _flags |= FLAG_FLUSHED_DIRTY;
-            }
-
-            lock();
-            locked = true;
-
-            // note that the field is in need of flushing again, and tell the
-            // broker too
-            _flush.clear(field);
-            _broker.setDirty(this, newFlush && !clean);
-
-            // save the field for rollback if needed
-            saveField(field);
-
-            // dirty the field and mark loaded; load fetch group if needed
-            int lockLevel = calculateLockLevel(active, true, null);
-            if (!_dirty.get(field)) {
-                setLoaded(field, true);
-                _dirty.set(field);
-
-                // make sure the field's fetch group is loaded
-                if (loadFetchGroup && isPersistent()
-                    && fmd.getManagement() == fmd.MANAGE_PERSISTENT)
-                    loadField(field, lockLevel, true, true);
-            }
-            obtainLocks(active, true, lockLevel, null, null);
-        } catch (RuntimeException re) {
-            throw translate(re);
-        } finally {
-            if (locked)
-                unlock();
-        }
-
-        if (clean)
-            return Boolean.TRUE;
-        if (newFlush) {
-            // this event can be fired later cause we're already dirty.
-            fireLifecycleEvent(LifecycleEvent.BEFORE_DIRTY_FLUSHED);
-            return null;
-        }
-        return Boolean.FALSE;
-    }
-
-    /**
-     * Fire post-dirty events after field value changes.
-     *
-     * @param status return value from {@link #dirty(int, Boolean, boolean)}
-     */
-    private void postDirty(Boolean status) {
-        if (Boolean.TRUE.equals(status))
-            fireLifecycleEvent(LifecycleEvent.AFTER_DIRTY);
-        else if (status == null)
-            fireLifecycleEvent(LifecycleEvent.AFTER_DIRTY_FLUSHED);
-    }
-
-    public void removed(int field, Object removed, boolean key) {
-        if (removed == null)
-            return;
-
-        try {
-            // dereference dependent fields, delete embedded
-            FieldMetaData fmd = _meta.getField(field);
-            ValueMetaData vmd = (key) ? fmd.getKey() : fmd.getElement();
-            if (vmd.isEmbeddedPC())
-                _single.delete(vmd, removed, null);
-            else if (vmd.getCascadeDelete() == ValueMetaData.CASCADE_AUTO)
-                _single.dereferenceDependent(removed);
-        } catch (RuntimeException re) {
-            throw translate(re);
-        }
-    }
-
-    public Object newProxy(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            return newFieldProxy(field);
-
-        switch (fmd.getTypeCode()) {
-            case JavaTypes.DATE:
-                if (fmd.getDeclaredType() == java.sql.Date.class)
-                    return new java.sql.Date(System.currentTimeMillis());
-                if (fmd.getDeclaredType() == java.sql.Timestamp.class)
-                    return new java.sql.Timestamp(System.currentTimeMillis());
-                if (fmd.getDeclaredType() == java.sql.Time.class)
-                    return new java.sql.Time(System.currentTimeMillis());
-                return new Date();
-            case JavaTypes.CALENDAR:
-                return Calendar.getInstance();
-            case JavaTypes.COLLECTION:
-                return new ArrayList();
-            case JavaTypes.MAP:
-                return new HashMap();
-        }
-        return null;
-    }
-
-    public Object newFieldProxy(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        ProxyManager mgr = _broker.getConfiguration().
-            getProxyManagerInstance();
-        Object init = fmd.getInitializer();
-
-        switch (fmd.getDeclaredTypeCode()) {
-            case JavaTypes.DATE:
-                return mgr.newDateProxy(fmd.getDeclaredType());
-            case JavaTypes.CALENDAR:
-                return mgr.newCalendarProxy(fmd.getDeclaredType(),
-                    init instanceof TimeZone ? (TimeZone) init : null);
-            case JavaTypes.COLLECTION:
-                return mgr.newCollectionProxy(fmd.getProxyType(),
-                    fmd.getElement().getDeclaredType(),
-                    init instanceof Comparator ? (Comparator) init : null);
-            case JavaTypes.MAP:
-                return mgr.newMapProxy(fmd.getProxyType(),
-                    fmd.getKey().getDeclaredType(),
-                    fmd.getElement().getDeclaredType(),
-                    init instanceof Comparator ? (Comparator) init : null);
-        }
-        return null;
-    }
-
-    public boolean isDefaultValue(int field) {
-        lock();
-        try {
-            _single.clear();
-            provideField(_pc, _single, field);
-            boolean ret = _single.isDefaultValue();
-            _single.clear();
-            return ret;
-        } finally {
-            unlock();
-        }
-    }
-
-    /////////////////////////////////////////////////////////
-    // Record that the field is dirty (which might load DFG)
-    /////////////////////////////////////////////////////////
-
-    public void settingBooleanField(PersistenceCapable pc, int field,
-        boolean curVal, boolean newVal, int set) {
-        if (set != SET_REMOTE) {
-            if (newVal == curVal && _loaded.get(field))
-                return;
-            assertNoPrimaryKeyChange(field);
-        }
-
-        lock();
-        try {
-            Boolean stat = dirty(field, Boolean.FALSE, set == SET_USER);
-            _single.storeBooleanField(field, newVal);
-            replaceField(pc, _single, field);
-            postDirty(stat);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingByteField(PersistenceCapable pc, int field,
-        byte curVal, byte newVal, int set) {
-        if (set != SET_REMOTE) {
-            if (newVal == curVal && _loaded.get(field))
-                return;
-            assertNoPrimaryKeyChange(field);
-        }
-
-        lock();
-        try {
-            Boolean stat = dirty(field, Boolean.FALSE, set == SET_USER);
-            _single.storeByteField(field, newVal);
-            replaceField(pc, _single, field);
-            postDirty(stat);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingCharField(PersistenceCapable pc, int field,
-        char curVal, char newVal, int set) {
-        if (set != SET_REMOTE) {
-            if (newVal == curVal && _loaded.get(field))
-                return;
-            assertNoPrimaryKeyChange(field);
-        }
-
-        lock();
-        try {
-            Boolean stat = dirty(field, Boolean.FALSE, set == SET_USER);
-            _single.storeCharField(field, newVal);
-            replaceField(pc, _single, field);
-            postDirty(stat);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingDoubleField(PersistenceCapable pc, int field,
-        double curVal, double newVal, int set) {
-        if (set != SET_REMOTE) {
-            if (newVal == curVal && _loaded.get(field))
-                return;
-            assertNoPrimaryKeyChange(field);
-        }
-
-        lock();
-        try {
-            Boolean stat = dirty(field, Boolean.FALSE, set == SET_USER);
-            _single.storeDoubleField(field, newVal);
-            replaceField(pc, _single, field);
-            postDirty(stat);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingFloatField(PersistenceCapable pc, int field,
-        float curVal, float newVal, int set) {
-        if (set != SET_REMOTE) {
-            if (newVal == curVal && _loaded.get(field))
-                return;
-            assertNoPrimaryKeyChange(field);
-        }
-
-        lock();
-        try {
-            Boolean stat = dirty(field, Boolean.FALSE, set == SET_USER);
-            _single.storeFloatField(field, newVal);
-            replaceField(pc, _single, field);
-            postDirty(stat);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingIntField(PersistenceCapable pc, int field,
-        int curVal, int newVal, int set) {
-        if (set != SET_REMOTE) {
-            if (newVal == curVal && _loaded.get(field))
-                return;
-            assertNoPrimaryKeyChange(field);
-        }
-
-        lock();
-        try {
-            Boolean stat = dirty(field, Boolean.FALSE, set == SET_USER);
-            _single.storeIntField(field, newVal);
-            replaceField(pc, _single, field);
-            postDirty(stat);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingLongField(PersistenceCapable pc, int field,
-        long curVal, long newVal, int set) {
-        if (set != SET_REMOTE) {
-            if (newVal == curVal && _loaded.get(field))
-                return;
-            assertNoPrimaryKeyChange(field);
-        }
-
-        lock();
-        try {
-            Boolean stat = dirty(field, Boolean.FALSE, set == SET_USER);
-            _single.storeLongField(field, newVal);
-            replaceField(pc, _single, field);
-            postDirty(stat);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingObjectField(PersistenceCapable pc, int field,
-        Object curVal, Object newVal, int set) {
-        if (set != SET_REMOTE) {
-            FieldMetaData fmd = _meta.getField(field);
-            if (_loaded.get(field)) {
-                if (newVal == curVal)
-                    return;
-
-                // only compare new to old values if the comparison is going to
-                // be cheap -- don't compare collections, maps, UDTs
-                switch (fmd.getDeclaredTypeCode()) {
-                    case JavaTypes.ARRAY:
-                    case JavaTypes.COLLECTION:
-                    case JavaTypes.MAP:
-                    case JavaTypes.PC:
-                    case JavaTypes.PC_UNTYPED:
-                        break;
-                    default:
-                        if (newVal != null && newVal.equals(curVal))
-                            return;
-                }
-            } else {
-                // if this is a dependent unloaded field, make sure to load
-                // it now
-                if (fmd.getCascadeDelete() == ValueMetaData.CASCADE_AUTO
-                    || fmd.getKey().getCascadeDelete()
-                    == ValueMetaData.CASCADE_AUTO
-                    || fmd.getElement().getCascadeDelete()
-                    == ValueMetaData.CASCADE_AUTO)
-                    curVal = fetchObjectField(field);
-            }
-
-            assertNoPrimaryKeyChange(field);
-            if (fmd.getDeclaredTypeCode() == JavaTypes.OID)
-                assertNotManagedObjectId(newVal);
-        }
-
-        lock();
-        try {
-            Boolean stat = dirty(field, Boolean.FALSE, set == SET_USER);
-            if (set != SET_REMOTE) {
-                _single.storeObjectField(field, curVal);
-                _single.unproxy();
-                _single.dereferenceDependent();
-                _single.clear();
-            }
-            _single.storeObjectField(field, newVal);
-            replaceField(pc, _single, field);
-            postDirty(stat);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingShortField(PersistenceCapable pc, int field,
-        short curVal, short newVal, int set) {
-        if (set != SET_REMOTE) {
-            if (newVal == curVal && _loaded.get(field))
-                return;
-            assertNoPrimaryKeyChange(field);
-        }
-
-        lock();
-        try {
-            Boolean stat = dirty(field, Boolean.FALSE, set == SET_USER);
-            _single.storeShortField(field, newVal);
-            replaceField(pc, _single, field);
-            postDirty(stat);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingStringField(PersistenceCapable pc, int field,
-        String curVal, String newVal, int set) {
-        if (set != SET_REMOTE) {
-            if (StringUtils.equals(newVal, curVal) && _loaded.get(field))
-                return;
-            assertNoPrimaryKeyChange(field);
-        }
-
-        lock();
-        try {
-            Boolean stat = dirty(field, Boolean.FALSE, set == SET_USER);
-            _single.storeStringField(field, newVal);
-            replaceField(pc, _single, field);
-            postDirty(stat);
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Disallows changing primary key fields for instances.
-     */
-    private void assertNoPrimaryKeyChange(int field) {
-        if (_oid != null && _meta.getField(field).isPrimaryKey())
-            throw translate(new InvalidStateException(_loc.get
-                ("change-identity")).setFailedObject(getManagedInstance()));
-    }
-
-    /**
-     * Disallows setting an object id field to a managed instance.
-     */
-    void assertNotManagedObjectId(Object val) {
-        if (val != null
-            && (ImplHelper.toPersistenceCapable(val,
-                 getContext().getConfiguration())).pcGetGenericContext()!= null)
-            throw translate(new InvalidStateException(_loc.get
-                ("managed-oid", Exceptions.toString(val),
-                    Exceptions.toString(getManagedInstance()))).
-                setFailedObject(getManagedInstance()));
-    }
-
-    ////////////////////////////
-    // Delegate to FieldManager
-    ////////////////////////////
-
-    public void providedBooleanField(PersistenceCapable pc, int field,
-        boolean curVal) {
-        _fm.storeBooleanField(field, curVal);
-    }
-
-    public void providedByteField(PersistenceCapable pc, int field,
-        byte curVal) {
-        _fm.storeByteField(field, curVal);
-    }
-
-    public void providedCharField(PersistenceCapable pc, int field,
-        char curVal) {
-        _fm.storeCharField(field, curVal);
-    }
-
-    public void providedDoubleField(PersistenceCapable pc, int field,
-        double curVal) {
-        _fm.storeDoubleField(field, curVal);
-    }
-
-    public void providedFloatField(PersistenceCapable pc, int field,
-        float curVal) {
-        _fm.storeFloatField(field, curVal);
-    }
-
-    public void providedIntField(PersistenceCapable pc, int field,
-        int curVal) {
-        _fm.storeIntField(field, curVal);
-    }
-
-    public void providedLongField(PersistenceCapable pc, int field,
-        long curVal) {
-        _fm.storeLongField(field, curVal);
-    }
-
-    public void providedObjectField(PersistenceCapable pc, int field,
-        Object curVal) {
-        _fm.storeObjectField(field, curVal);
-    }
-
-    public void providedShortField(PersistenceCapable pc, int field,
-        short curVal) {
-        _fm.storeShortField(field, curVal);
-    }
-
-    public void providedStringField(PersistenceCapable pc, int field,
-        String curVal) {
-        _fm.storeStringField(field, curVal);
-    }
-
-    public boolean replaceBooleanField(PersistenceCapable pc, int field) {
-        return _fm.fetchBooleanField(field);
-    }
-
-    public byte replaceByteField(PersistenceCapable pc, int field) {
-        return _fm.fetchByteField(field);
-    }
-
-    public char replaceCharField(PersistenceCapable pc, int field) {
-        return _fm.fetchCharField(field);
-    }
-
-    public double replaceDoubleField(PersistenceCapable pc, int field) {
-        return _fm.fetchDoubleField(field);
-    }
-
-    public float replaceFloatField(PersistenceCapable pc, int field) {
-        return _fm.fetchFloatField(field);
-    }
-
-    public int replaceIntField(PersistenceCapable pc, int field) {
-        return _fm.fetchIntField(field);
-    }
-
-    public long replaceLongField(PersistenceCapable pc, int field) {
-        return _fm.fetchLongField(field);
-    }
-
-    public Object replaceObjectField(PersistenceCapable pc, int field) {
-        return _fm.fetchObjectField(field);
-    }
-
-    public short replaceShortField(PersistenceCapable pc, int field) {
-        return _fm.fetchShortField(field);
-    }
-
-    public String replaceStringField(PersistenceCapable pc, int field) {
-        return _fm.fetchStringField(field);
-    }
-
-    //////////////////////////////////
-    // Implementation of FieldManager
-    //////////////////////////////////
-
-    public boolean fetchBoolean(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            return fetchBooleanField(field);
-
-        Object val = fetchField(field, false);
-        return ((Boolean) fmd.getExternalValue(val, _broker)).booleanValue();
-    }
-
-    public boolean fetchBooleanField(int field) {
-        lock();
-        try {
-            if (!_loaded.get(field))
-                loadField(field, LockLevels.LOCK_NONE, false, false);
-
-            provideField(_pc, _single, field);
-            return _single.fetchBooleanField(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public byte fetchByte(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            return fetchByteField(field);
-
-        Object val = fetchField(field, false);
-        return ((Number) fmd.getExternalValue(val, _broker)).byteValue();
-    }
-
-    public byte fetchByteField(int field) {
-        lock();
-        try {
-            if (!_loaded.get(field))
-                loadField(field, LockLevels.LOCK_NONE, false, false);
-
-            provideField(_pc, _single, field);
-            return _single.fetchByteField(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public char fetchChar(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            return fetchCharField(field);
-
-        Object val = fetchField(field, false);
-        return ((Character) fmd.getExternalValue(val, _broker)).charValue();
-    }
-
-    public char fetchCharField(int field) {
-        lock();
-        try {
-            if (!_loaded.get(field))
-                loadField(field, LockLevels.LOCK_NONE, false, false);
-
-            provideField(_pc, _single, field);
-            return _single.fetchCharField(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public double fetchDouble(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            return fetchDoubleField(field);
-
-        Object val = fetchField(field, false);
-        return ((Number) fmd.getExternalValue(val, _broker)).doubleValue();
-    }
-
-    public double fetchDoubleField(int field) {
-        lock();
-        try {
-            if (!_loaded.get(field))
-                loadField(field, LockLevels.LOCK_NONE, false, false);
-
-            provideField(_pc, _single, field);
-            return _single.fetchDoubleField(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public float fetchFloat(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            return fetchFloatField(field);
-
-        Object val = fetchField(field, false);
-        return ((Number) fmd.getExternalValue(val, _broker)).floatValue();
-    }
-
-    public float fetchFloatField(int field) {
-        lock();
-        try {
-            if (!_loaded.get(field))
-                loadField(field, LockLevels.LOCK_NONE, false, false);
-
-            provideField(_pc, _single, field);
-            return _single.fetchFloatField(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public int fetchInt(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            return fetchIntField(field);
-
-        Object val = fetchField(field, false);
-        return ((Number) fmd.getExternalValue(val, _broker)).intValue();
-    }
-
-    public int fetchIntField(int field) {
-        lock();
-        try {
-            if (!_loaded.get(field))
-                loadField(field, LockLevels.LOCK_NONE, false, false);
-
-            provideField(_pc, _single, field);
-            return _single.fetchIntField(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public long fetchLong(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            return fetchLongField(field);
-
-        Object val = fetchField(field, false);
-        return ((Number) fmd.getExternalValue(val, _broker)).longValue();
-    }
-
-    public long fetchLongField(int field) {
-        lock();
-        try {
-            if (!_loaded.get(field))
-                loadField(field, LockLevels.LOCK_NONE, false, false);
-
-            provideField(_pc, _single, field);
-            return _single.fetchLongField(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public Object fetchObject(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            return fetchObjectField(field);
-
-        Object val = fetchField(field, false);
-        return fmd.getExternalValue(val, _broker);
-    }
-
-    public Object fetchObjectField(int field) {
-        lock();
-        try {
-            if (!_loaded.get(field))
-                loadField(field, LockLevels.LOCK_NONE, false, false);
-
-            provideField(_pc, _single, field);
-            return _single.fetchObjectField(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public short fetchShort(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            return fetchShortField(field);
-
-        Object val = fetchField(field, false);
-        return ((Number) fmd.getExternalValue(val, _broker)).shortValue();
-    }
-
-    public short fetchShortField(int field) {
-        lock();
-        try {
-            if (!_loaded.get(field))
-                loadField(field, LockLevels.LOCK_NONE, false, false);
-
-            provideField(_pc, _single, field);
-            return _single.fetchShortField(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public String fetchString(int field) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            return fetchStringField(field);
-
-        Object val = fetchField(field, false);
-        return (String) fmd.getExternalValue(val, _broker);
-    }
-
-    public String fetchStringField(int field) {
-        lock();
-        try {
-            if (!_loaded.get(field))
-                loadField(field, LockLevels.LOCK_NONE, false, false);
-
-            provideField(_pc, _single, field);
-            return _single.fetchStringField(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeBoolean(int field, boolean externalVal) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            storeBooleanField(field, externalVal);
-        else {
-            Object val = (externalVal) ? Boolean.TRUE : Boolean.FALSE;
-            storeField(field, fmd.getFieldValue(val, _broker));
-        }
-    }
-
-    public void storeBooleanField(int field, boolean curVal) {
-        lock();
-        try {
-            _single.storeBooleanField(field, curVal);
-            replaceField(_pc, _single, field);
-            setLoaded(field, true);
-            postLoad(field, null);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeByte(int field, byte externalVal) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            storeByteField(field, externalVal);
-        else
-            storeField(field, fmd.getFieldValue(new Byte(externalVal),
-                _broker));
-    }
-
-    public void storeByteField(int field, byte curVal) {
-        lock();
-        try {
-            _single.storeByteField(field, curVal);
-            replaceField(_pc, _single, field);
-            setLoaded(field, true);
-            postLoad(field, null);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeChar(int field, char externalVal) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            storeCharField(field, externalVal);
-        else
-            storeField(field, fmd.getFieldValue(new Character(externalVal),
-                _broker));
-    }
-
-    public void storeCharField(int field, char curVal) {
-        lock();
-        try {
-            _single.storeCharField(field, curVal);
-            replaceField(_pc, _single, field);
-            setLoaded(field, true);
-            postLoad(field, null);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeDouble(int field, double externalVal) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            storeDoubleField(field, externalVal);
-        else
-            storeField(field, fmd.getFieldValue(new Double(externalVal),
-                _broker));
-    }
-
-    public void storeDoubleField(int field, double curVal) {
-        lock();
-        try {
-            _single.storeDoubleField(field, curVal);
-            replaceField(_pc, _single, field);
-            setLoaded(field, true);
-            postLoad(field, null);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeFloat(int field, float externalVal) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            storeFloatField(field, externalVal);
-        else
-            storeField(field, fmd.getFieldValue(new Float(externalVal),
-                _broker));
-    }
-
-    public void storeFloatField(int field, float curVal) {
-        lock();
-        try {
-            _single.storeFloatField(field, curVal);
-            replaceField(_pc, _single, field);
-            setLoaded(field, true);
-            postLoad(field, null);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeInt(int field, int externalVal) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            storeIntField(field, externalVal);
-        else
-            storeField(field, fmd.getFieldValue(Numbers.valueOf(externalVal),
-                _broker));
-    }
-
-    public void storeIntField(int field, int curVal) {
-        lock();
-        try {
-            _single.storeIntField(field, curVal);
-            replaceField(_pc, _single, field);
-            setLoaded(field, true);
-            postLoad(field, null);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeLong(int field, long externalVal) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            storeLongField(field, externalVal);
-        else
-            storeField(field, fmd.getFieldValue(Numbers.valueOf(externalVal),
-                _broker));
-    }
-
-    public void storeLongField(int field, long curVal) {
-        lock();
-        try {
-            _single.storeLongField(field, curVal);
-            replaceField(_pc, _single, field);
-            setLoaded(field, true);
-            postLoad(field, null);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeObject(int field, Object externalVal) {
-        FieldMetaData fmd = _meta.getField(field);
-        externalVal = fmd.order(externalVal);
-        if (!fmd.isExternalized())
-            storeObjectField(field, externalVal);
-        else
-            storeField(field, fmd.getFieldValue(externalVal, _broker));
-    }
-
-    public void storeObjectField(int field, Object curVal) {
-        lock();
-        try {
-            _single.storeObjectField(field, curVal);
-            _single.proxy(true, false);
-            replaceField(_pc, _single, field);
-            setLoaded(field, true);
-            postLoad(field, null);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeShort(int field, short externalVal) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            storeShortField(field, externalVal);
-        else
-            storeField(field, fmd.getFieldValue(new Short(externalVal),
-                _broker));
-    }
-
-    public void storeShortField(int field, short curVal) {
-        lock();
-        try {
-            _single.storeShortField(field, curVal);
-            replaceField(_pc, _single, field);
-            setLoaded(field, true);
-            postLoad(field, null);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeString(int field, String externalVal) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (!fmd.isExternalized())
-            storeStringField(field, externalVal);
-        else
-            storeField(field, fmd.getFieldValue(externalVal, _broker));
-    }
-
-    public void storeStringField(int field, String curVal) {
-        lock();
-        try {
-            _single.storeStringField(field, curVal);
-            replaceField(_pc, _single, field);
-            setLoaded(field, true);
-            postLoad(field, null);
-        } finally {
-            unlock();
-        }
-    }
-
-    /**
-     * Store the given field value into the given field manager.
-     */
-    private void storeField(int field, Object val, FieldManager fm) {
-        FieldMetaData fmd = _meta.getField(field);
-        if (fmd == null)
-            throw new UserException(_loc.get("no-field-index",
-                String.valueOf(field), _meta.getDescribedType())).
-                setFailedObject(getManagedInstance());
-
-        switch (fmd.getDeclaredTypeCode()) {
-            case JavaTypes.BOOLEAN:
-                boolean bool = val != null && ((Boolean) val).booleanValue();
-                fm.storeBooleanField(field, bool);
-                break;
-            case JavaTypes.BYTE:
-                byte b = (val == null) ? 0 : ((Number) val).byteValue();
-                fm.storeByteField(field, b);
-                break;
-            case JavaTypes.CHAR:
-                char c = (val == null) ? 0 : ((Character) val).charValue();
-                fm.storeCharField(field, c);
-                break;
-            case JavaTypes.DOUBLE:
-                double d = (val == null) ? 0 : ((Number) val).doubleValue();
-                fm.storeDoubleField(field, d);
-                break;
-            case JavaTypes.FLOAT:
-                float f = (val == null) ? 0 : ((Number) val).floatValue();
-                fm.storeFloatField(field, f);
-                break;
-            case JavaTypes.INT:
-                int i = (val == null) ? 0 : ((Number) val).intValue();
-                fm.storeIntField(field, i);
-                break;
-            case JavaTypes.LONG:
-                long l = (val == null) ? 0 : ((Number) val).longValue();
-                fm.storeLongField(field, l);
-                break;
-            case JavaTypes.SHORT:
-                short s = (val == null) ? 0 : ((Number) val).shortValue();
-                fm.storeShortField(field, s);
-                break;
-            case JavaTypes.STRING:
-                fm.storeStringField(field, (String) val);
-                break;
-            default:
-                fm.storeObjectField(field, val);
-        }
-    }
-
-    /////////////
-    // Utilities
-    /////////////
-
-    /**
-     * Erase the fact that this instance has been flushed.
-     */
-    void eraseFlush() {
-        _flags &= ~FLAG_FLUSHED;
-        _flags &= ~FLAG_FLUSHED_DIRTY;
-
-        int fmds = _meta.getFields().length;
-        for (int i = 0; i < fmds; i++)
-            _flush.clear(i);
-    }
-
-    /**
-     * Records that all instance fields are/are not loaded.
-     * Primary key and non-persistent fields are not affected.
-     */
-    void setLoaded(boolean val) {
-        FieldMetaData[] fmds = _meta.getFields();
-        for (int i = 0; i < fmds.length; i++) {
-            if (!fmds[i].isPrimaryKey()
-                && fmds[i].getManagement() == fmds[i].MANAGE_PERSISTENT)
-                setLoaded(i, val);
-        }
-        if (!val) {
-            _flags &= ~FLAG_LOADED;
-            setDirty(false);
-        } else
-            _flags |= FLAG_LOADED;
-    }
-
-    /**
-     * Records that all instance fields are/are not dirty,
-     * and changes the flags of the instance accordingly.
-     */

[... 3925 lines stripped ...]


Re: svn commit: r700563 [2/3] - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbedded.java

Posted by Kevin Sutter <kw...@gmail.com>.
Jeremy,
Did you provide a commit message with this commit?  Also, was this in
response to a JIRA issue?  The commit message should have the JIRA Issue
identified somewhere in the first line of text so that the changes are
associated with the proper JIRA Issue.  Something like...

OPENJPA-xxx.  This commit resolves the issue with...

Thanks,
Kevin

On Tue, Sep 30, 2008 at 3:17 PM, Jeremy Bauer <te...@gmail.com> wrote:

> Hi Craig.
>
> EOL issue.  I Eclipse diff'ed before committing & it did not show the
> EOL change.  Mike Dick pointed me to instructions for configuring my
> svn properties so it shouldn't happen again.  I'll be using svn diff
> from now on...
>
> -Jeremy
>

Re: svn commit: r700563 [2/3] - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbedded.java

Posted by Jeremy Bauer <te...@gmail.com>.
Hi Craig.

EOL issue.  I Eclipse diff'ed before committing & it did not show the
EOL change.  Mike Dick pointed me to instructions for configuring my
svn properties so it shouldn't happen again.  I'll be using svn diff
from now on...

-Jeremy

Re: svn commit: r700563 [2/3] - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbedded.java

Posted by Craig L Russell <Cr...@Sun.COM>.
What went wrong? This diff is impossible. Line ending issues? Did you  
svn diff before committing?

Craig

On Sep 30, 2008, at 12:42 PM, jrbauer@apache.org wrote:

>
> Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/ 
> openjpa/kernel/StateManagerImpl.java
> URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=700563&r1=700562&r2=700563&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ 
> kernel/StateManagerImpl.java (original)
> +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ 
> kernel/StateManagerImpl.java Tue Sep 30 12:42:11 2008
> @@ -1,3258 +1,3259 @@
> -/*
> - * Licensed to the Apache Software Foundation (ASF) under one
> - * or more contributor license agreements.  See the NOTICE file
> - * distributed with this work for additional information
> - * regarding copyright ownership.  The ASF licenses this file
> - * to you under the Apache License, Version 2.0 (the
> - * "License"); you may not use this file except in compliance
> - * with the License.  You may obtain a copy of the License at
> - *
> - * http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing,
> - * software distributed under the License is distributed on an
> - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> - * KIND, either express or implied.  See the License for the
> - * specific language governing permissions and limitations
> - * under the License.
> - */
> -package org.apache.openjpa.kernel;
> -
> -import java.io.IOException;
> -import java.io.NotSerializableException;
> -import java.io.ObjectInputStream;
> -import java.io.ObjectOutput;
> -import java.io.ObjectOutputStream;
> -import java.io.Serializable;
> -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.Iterator;
> -import java.util.TimeZone;
> -
> -import org.apache.commons.lang.StringUtils;
> -import org.apache.openjpa.conf.OpenJPAConfiguration;
> -import org.apache.openjpa.enhance.DynamicPersistenceCapable;
> -import org.apache.openjpa.enhance.FieldManager;
> -import org.apache.openjpa.enhance.ManagedInstanceProvider;
> -import org.apache.openjpa.enhance.PCRegistry;
> -import org.apache.openjpa.enhance.PersistenceCapable;
> -import org.apache.openjpa.enhance.RedefinitionHelper;
> -import org.apache.openjpa.enhance.StateManager;
> -import org.apache.openjpa.event.LifecycleEvent;
> -import org.apache.openjpa.event.LifecycleEventManager;
> -import org.apache.openjpa.lib.util.Localizer;
> -import org.apache.openjpa.meta.ClassMetaData;
> -import org.apache.openjpa.meta.FetchGroup;
> -import org.apache.openjpa.meta.FieldMetaData;
> -import org.apache.openjpa.meta.JavaTypes;
> -import org.apache.openjpa.meta.UpdateStrategies;
> -import org.apache.openjpa.meta.ValueMetaData;
> -import org.apache.openjpa.meta.ValueStrategies;
> -import org.apache.openjpa.util.ApplicationIds;
> -import org.apache.openjpa.util.Exceptions;
> -import org.apache.openjpa.util.ImplHelper;
> -import org.apache.openjpa.util.InternalException;
> -import org.apache.openjpa.util.InvalidStateException;
> -import org.apache.openjpa.util.ObjectNotFoundException;
> -import org.apache.openjpa.util.OpenJPAId;
> -import org.apache.openjpa.util.ProxyManager;
> -import org.apache.openjpa.util.RuntimeExceptionTranslator;
> -import org.apache.openjpa.util.UserException;
> -import serp.util.Numbers;
> -
> -/**
> - * Implementation of the {@link OpenJPAStateManager} interface for  
> use
> - * with this runtime. Each state manager manages the state of a  
> single
> - * persistence capable instance. The state manager is also  
> responsible for
> - * all communications about the instance to the {@link StoreManager}.
> - *  The state manager uses the State pattern in both its  
> interaction with
> - * the governed instance and its interaction with the broker.
> - * In its interactions with the persistence capable instance, it  
> uses the
> - * {@link FieldManager} interface. Similarly, when interacting with  
> the
> - * broker, it uses the {@link PCState} singleton that represents
> - * the current lifecycle state of the instance.
> - *
> - * @author Abe White
> - */
> -public class StateManagerImpl
> -    implements OpenJPAStateManager, Serializable {
> -
> -    public static final int LOAD_FGS = 0;
> -    public static final int LOAD_ALL = 1;
> -    public static final int LOAD_SERIALIZE = 2;
> -
> -    private static final int FLAG_SAVE = 2 << 0;
> -    private static final int FLAG_DEREF = 2 << 1;
> -    private static final int FLAG_LOADED = 2 << 2;
> -    private static final int FLAG_READ_LOCKED = 2 << 3;
> -    private static final int FLAG_WRITE_LOCKED = 2 << 4;
> -    private static final int FLAG_OID_ASSIGNED = 2 << 5;
> -    private static final int FLAG_LOADING = 2 << 6;
> -    private static final int FLAG_PRE_DELETING = 2 << 7;
> -    private static final int FLAG_FLUSHED = 2 << 8;
> -    private static final int FLAG_PRE_FLUSHED = 2 << 9;
> -    private static final int FLAG_FLUSHED_DIRTY = 2 << 10;
> -    private static final int FLAG_IMPL_CACHE = 2 << 11;
> -    private static final int FLAG_INVERSES = 2 << 12;
> -    private static final int FLAG_NO_UNPROXY = 2 << 13;
> -    private static final int FLAG_VERSION_CHECK = 2 << 14;
> -    private static final int FLAG_VERSION_UPDATE = 2 << 15;
> -    private static final int FLAG_DETACHING = 2 << 16;
> -
> -    private static final Localizer _loc = Localizer.forPackage
> -        (StateManagerImpl.class);
> -
> -    // information about the instance
> -    private transient PersistenceCapable _pc = null;
> -    private transient ClassMetaData _meta = null;
> -    private BitSet _loaded = null;
> -    private BitSet _dirty = null;
> -    private BitSet _flush = null;
> -    private int _flags = 0;
> -
> -    // id is the state manager identity; oid is the persistent  
> identity.  oid
> -    // may be null for embedded and transient-transactional objects  
> or new
> -    // instances that haven't been assigned an oid.  id is  
> reassigned to oid
> -    // on successful oid assignment (or flush completion if  
> assignment is
> -    // during flush)
> -    private Object _id = null;
> -    private Object _oid = null;
> -
> -    // the managing persistence manager and lifecycle state
> -    private transient BrokerImpl _broker; // this is serialized  
> specially
> -    private PCState _state = PCState.TRANSIENT;
> -
> -    // the current and last loaded version indicators, and the lock  
> object
> -    private Object _version = null;
> -    private Object _loadVersion = null;
> -    private Object _lock = null;
> -    private int _readLockLevel = -1;
> -    private int _writeLockLevel = -1;
> -
> -    // delegates when providing/replacing instance data
> -    private SingleFieldManager _single = null;
> -    private SaveFieldManager _saved = null;
> -    private FieldManager _fm = null;
> -
> -    // impldata; field impldata and intermediate data share the  
> same array
> -    private Object _impl = null;
> -    private Object[] _fieldImpl = null;
> -
> -    // information about the owner of this instance, if it is  
> embedded
> -    private StateManagerImpl _owner = null;
> -    private int _ownerIndex = -1;
> -
> -    /**
> -     * Constructor; supply id, type metadata, and owning  
> persistence manager.
> -     */
> -    protected StateManagerImpl(Object id, ClassMetaData meta,
> -        BrokerImpl broker) {
> -        _id = id;
> -        _meta = meta;
> -        _broker = broker;
> -        _single = new SingleFieldManager(this, broker);
> -
> -        if (_meta.getIdentityType() == ClassMetaData.ID_UNKNOWN)
> -            throw new UserException(_loc.get("meta-unknownid",  
> _meta));
> -    }
> -
> -    /**
> -     * Set the owning state and field if this is an embedded  
> instance.
> -     */
> -    void setOwner(StateManagerImpl owner, ValueMetaData ownerMeta) {
> -        _owner = owner;
> -        _ownerIndex = ownerMeta.getFieldMetaData().getIndex();
> -    }
> -
> -    /**
> -     * Whether this state manager is in the middle of a load.
> -     */
> -    boolean isLoading() {
> -        return (_flags & FLAG_LOADING) > 0;
> -    }
> -
> -    /**
> -     * Whether this state manager is in the middle of a load  
> initiated
> -     * by outside code; for any internal methods that cause  
> loading, the
> -     * loading flag is set automatically.
> -     */
> -    void setLoading(boolean loading) {
> -        if (loading)
> -            _flags |= FLAG_LOADING;
> -        else
> -            _flags &= ~FLAG_LOADING;
> -    }
> -
> -    /**
> -     * Set or reset the lifecycle state of the managed instance. If  
> the
> -     * transactional state of the instance changes, it will be  
> enlisted/
> -     * delisted from the current transaction as necessary. The given
> -     * state will be initialized after being set. If the given state
> -     * is the same as the current state, this method will have no  
> effect.
> -     */
> -    private void setPCState(PCState state) {
> -        if (_state == state)
> -            return;
> -
> -        lock();
> -        try {
> -            // notify the store manager that we're changing states;  
> can veto
> -            _broker.getStoreManager().beforeStateChange(this,  
> _state, state);
> -
> -            // replace state
> -            boolean wasDeleted = _state.isDeleted();
> -            boolean wasDirty = _state.isDirty();
> -            boolean wasPending = _state.isPendingTransactional();
> -            _state = state;
> -
> -            // enlist/delist from transaction
> -            if (_state.isTransactional()) {
> -                _broker.addToTransaction(this);
> -                if (_state.isDeleted() != wasDeleted)
> -                    _broker.setDirty(this, !wasDirty || isFlushed());
> -                else if (_state.isDirty() && !wasDirty)
> -                    _broker.setDirty(this, true);
> -            } else if (!wasPending &&  
> _state.isPendingTransactional())
> -                _broker.addToPendingTransaction(this);
> -            else if (wasPending && !_state.isPendingTransactional())
> -                _broker.removeFromPendingTransaction(this);
> -            else
> -                _broker.removeFromTransaction(this);
> -
> -            // initialize
> -            _state.initialize(this);
> -            if (_state.isDeleted() && !wasDeleted)
> -                fireLifecycleEvent(LifecycleEvent.AFTER_DELETE);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    //////////////////////////////////////
> -    // OpenJPAStateManager implementation
> -    //////////////////////////////////////
> -
> -    public void initialize(Class cls, PCState state) {
> -        // check to see if our current object id instance is the
> -        // correct id type for the specified class; this is for cases
> -        // when we have an application id hierarchy and we had set  
> the
> -        // metadata to a superclass id -- the subclass' id may be a
> -        // different class, so we need to reset it
> -        if (_meta.getDescribedType() != cls) {
> -            ClassMetaData sub = _meta.getRepository().getMetaData
> -                (cls, _broker.getClassLoader(), true);
> -            if (_oid != null) {
> -                if (_meta.getIdentityType() ==  
> ClassMetaData.ID_DATASTORE)
> -                    _oid =  
> _broker.getStoreManager().copyDataStoreId(_oid,
> -                        sub);
> -                else if (_meta.isOpenJPAIdentity())
> -                    _oid = ApplicationIds.copy(_oid, sub);
> -                else if (sub.getObjectIdType() !=  
> _meta.getObjectIdType()) {
> -                    Object[] pkFields =  
> ApplicationIds.toPKValues(_oid, _meta);
> -                    _oid = ApplicationIds.fromPKValues(pkFields,  
> sub);
> -                }
> -            }
> -            _meta = sub;
> -        }
> -
> -        PersistenceCapable inst = PCRegistry.newInstance(cls, this,  
> _oid, true);
> -        if (inst == null) {
> -            // the instance was null: check to see if the instance is
> -            // abstract (as can sometimes be the case when the
> -            // class discriminator strategy is not configured  
> correctly)
> -            if (Modifier.isAbstract(cls.getModifiers()))
> -                throw new UserException(_loc.get("instantiate- 
> abstract",
> -                    cls.getName(), _oid));
> -            throw new InternalException();
> -        }
> -
> -        initialize(inst, state);
> -    }
> -
> -    /**
> -     * Initialize with the given instance and state.
> -     */
> -    protected void initialize(PersistenceCapable pc, PCState state) {
> -        if (pc == null)
> -            throw new UserException(_loc.get("init-null-pc", _meta));
> -        if (pc.pcGetStateManager() != null &&  
> pc.pcGetStateManager() != this)
> -            throw new UserException(_loc.get("init-sm-pc",
> -                Exceptions.toString(pc))).setFailedObject(pc);
> -        pc.pcReplaceStateManager(this);
> -
> -        FieldMetaData[] fmds = _meta.getFields();
> -        _loaded = new BitSet(fmds.length);
> -        _flush = new BitSet(fmds.length);
> -        _dirty = new BitSet(fmds.length);
> -
> -        for (int i = 0; i < fmds.length; i++) {
> -            // mark primary key and non-persistent fields as loaded
> -            if (fmds[i].isPrimaryKey()
> -                || fmds[i].getManagement() !=  
> fmds[i].MANAGE_PERSISTENT)
> -                _loaded.set(i);
> -
> -            // record whether there are any managed inverse fields
> -            if (_broker.getInverseManager() != null
> -                && fmds[i].getInverseMetaDatas().length > 0)
> -                _flags |= FLAG_INVERSES;
> -        }
> -
> -        pc.pcSetDetachedState(null);
> -        _pc = pc;
> -
> -        if (_oid instanceof OpenJPAId)
> -            ((OpenJPAId)  
> _oid).setManagedInstanceType(_meta.getDescribedType());
> -
> -        // initialize our state and add ourselves to the broker's  
> cache
> -        setPCState(state);
> -        if (_broker.getStateManagerImplById(getObjectId(), false)  
> == null) {
> -        	_broker.setStateManager(_id, this, BrokerImpl.STATUS_INIT);
> -        }
> -        if (state == PCState.PNEW)
> -            fireLifecycleEvent(LifecycleEvent.AFTER_PERSIST);
> -
> -        // if this is a non-tracking PC, add a hard ref to the  
> appropriate data
> -        // sets and give it an opportunity to make a state snapshot.
> -        if (!isIntercepting()) {
> -            saveFields(true);
> -            if (!isNew())
> -                RedefinitionHelper.assignLazyLoadProxies(this);
> -        }
> -    }
> -
> -    /**
> -     * Whether or not data access in this instance is intercepted.  
> This differs
> -     * from {@link ClassMetaData#isIntercepting()} in that it  
> checks for
> -     * property access + subclassing in addition to the  
> redefinition /
> -     * enhancement checks.
> -     *
> -     * @since 1.0.0
> -     */
> -    public boolean isIntercepting() {
> -        if (getMetaData().isIntercepting())
> -            return true;
> -        if (getMetaData().getAccessType() !=  
> ClassMetaData.ACCESS_FIELD
> -            && _pc instanceof DynamicPersistenceCapable)
> -            return true;
> -
> -        return false;
> -    }
> -
> -    /**
> -     * Fire the given lifecycle event to all listeners.
> -     */
> -    private boolean fireLifecycleEvent(int type) {
> -        return _broker.fireLifecycleEvent(getManagedInstance(), null,
> -            _meta, type);
> -    }
> -
> -    public void load(FetchConfiguration fetch) {
> -        load(fetch, LOAD_FGS, null, null, false);
> -    }
> -
> -    /**
> -     * Load the state of this instance based on the given fetch  
> configuration
> -     * and load mode. Return true if any data was loaded, false  
> otherwise.
> -     */
> -    protected boolean load(FetchConfiguration fetch, int loadMode,
> -        BitSet exclude, Object sdata, boolean forWrite) {
> -        if (!forWrite && (!isPersistent() || isNew() || isDeleted()))
> -            return false;
> -
> -        // if any fields being loaded, do state transitions for read
> -        BitSet fields = getUnloadedInternal(fetch, loadMode,  
> exclude);
> -        boolean active = _broker.isActive();
> -        if (!forWrite && fields != null)
> -            beforeRead(-1);
> -
> -        // call load even if no fields are being loaded, because it  
> takes
> -        // care of checking if the DFG is loaded, making sure  
> version info
> -        // is loaded, etc
> -        int lockLevel = calculateLockLevel(active, forWrite, fetch);
> -        boolean ret = loadFields(fields, fetch, lockLevel, sdata);
> -        obtainLocks(active, forWrite, lockLevel, fetch, sdata);
> -        return ret;
> -    }
> -
> -    public Object getManagedInstance() {
> -        if (_pc instanceof ManagedInstanceProvider)
> -            return ((ManagedInstanceProvider)  
> _pc).getManagedInstance();
> -        else
> -            return _pc;
> -    }
> -
> -    public PersistenceCapable getPersistenceCapable() {
> -        return _pc;
> -    }
> -
> -    public ClassMetaData getMetaData() {
> -        return _meta;
> -    }
> -
> -    public OpenJPAStateManager getOwner() {
> -        return _owner;
> -    }
> -
> -    public int getOwnerIndex() {
> -        return _ownerIndex;
> -    }
> -
> -    public boolean isEmbedded() {
> -        return _owner != null;
> -    }
> -
> -    public boolean isFlushed() {
> -        return (_flags & FLAG_FLUSHED) > 0;
> -    }
> -
> -    public boolean isFlushedDirty() {
> -        return (_flags & FLAG_FLUSHED_DIRTY) > 0;
> -    }
> -
> -    public BitSet getLoaded() {
> -        return _loaded;
> -    }
> -
> -    public BitSet getFlushed() {
> -        return _flush;
> -    }
> -
> -    public BitSet getDirty() {
> -        return _dirty;
> -    }
> -
> -    public BitSet getUnloaded(FetchConfiguration fetch) {
> -        // collect fields to load from data store based on fetch  
> configuration
> -        BitSet fields = getUnloadedInternal(fetch, LOAD_FGS, null);
> -        return (fields == null) ? new BitSet(0) : fields;
> -    }
> -
> -    /**
> -     * Internal version of {@link OpenJPAStateManager#getUnloaded}  
> that avoids
> -     * creating an empty bit set by returning null when there are  
> no unloaded
> -     * fields.
> -     */
> -    private BitSet getUnloadedInternal(FetchConfiguration fetch,  
> int mode,
> -        BitSet exclude) {
> -        if (exclude == StoreContext.EXCLUDE_ALL)
> -            return null;
> -
> -        BitSet fields = null;
> -        FieldMetaData[] fmds = _meta.getFields();
> -        boolean load;
> -        for (int i = 0; i < fmds.length; i++) {
> -            if (_loaded.get(i) || (exclude != null &&  
> exclude.get(i)))
> -                continue;
> -
> -            switch (mode) {
> -                case LOAD_SERIALIZE:
> -                    load = !fmds[i].isTransient();
> -                    break;
> -                case LOAD_FGS:
> -                    load = fetch == null ||  
> fetch.requiresFetch(fmds[i])
> -                        != FetchConfiguration.FETCH_NONE;
> -                    break;
> -                default: // LOAD_ALL
> -                    load = true;
> -            }
> -
> -            if (load) {
> -                if (fields == null)
> -                    fields = new BitSet(fmds.length);
> -                fields.set(i);
> -            }
> -        }
> -        return fields;
> -    }
> -
> -    public StoreContext getContext() {
> -        return _broker;
> -    }
> -
> -    /**
> -     * Managing broker.
> -     */
> -    BrokerImpl getBroker() {
> -        return _broker;
> -    }
> -
> -    public Object getId() {
> -        return _id;
> -    }
> -
> -    public Object getObjectId() {
> -        StateManagerImpl sm = this;
> -        while (sm.getOwner() != null)
> -            sm = (StateManagerImpl) sm.getOwner();
> -        return sm._oid;
> -    }
> -
> -    public void setObjectId(Object oid) {
> -        _oid = oid;
> -        if (_pc != null && oid instanceof OpenJPAId)
> -            ((OpenJPAId)  
> oid).setManagedInstanceType(_meta.getDescribedType());
> -    }
> -
> -    public boolean assignObjectId(boolean flush) {
> -        lock();
> -        try {
> -            return assignObjectId(flush, false);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    /**
> -     * Ask store manager to assign our oid, optionally flushing and
> -     * optionally recaching on the new oid.
> -     */
> -    boolean assignObjectId(boolean flush, boolean preFlushing) {
> -        if (_oid != null || isEmbedded() || !isPersistent())
> -            return true;
> -
> -        if (_broker.getStoreManager().assignObjectId(this,  
> preFlushing)) {
> -            if (!preFlushing)
> -                assertObjectIdAssigned(true);
> -        } else if (flush)
> -            _broker.flush();
> -        else
> -            return false;
> -        return true;
> -    }
> -
> -    /**
> -     * Make sure we were assigned an oid, and perform actions to  
> make it
> -     * permanent.
> -     *
> -     * @param recache whether to recache ourself on the new oid
> -     */
> -    private void assertObjectIdAssigned(boolean recache) {
> -        if (!isNew() || isDeleted() || isProvisional()
> -            || (_flags & FLAG_OID_ASSIGNED) != 0)
> -            return;
> -        if (_oid == null) {
> -            if (_meta.getIdentityType() ==  
> ClassMetaData.ID_DATASTORE)
> -                throw new InternalException(Exceptions.toString
> -                    (getManagedInstance()));
> -            _oid = ApplicationIds.create(_pc, _meta);
> -        }
> -
> -        Object orig = _id;
> -        _id = _oid;
> -        if (recache) {
> -            try {
> -                _broker.setStateManager(orig, this,
> -                    BrokerImpl.STATUS_OID_ASSIGN);
> -            } catch (RuntimeException re) {
> -                _id = orig;
> -                _oid = null;
> -                throw re;
> -            }
> -        }
> -        _flags |= FLAG_OID_ASSIGNED;
> -    }
> -
> -    /**
> -     * Assign the proper generated value to the given field based  
> on its
> -     * value-strategy.
> -     */
> -    private boolean assignField(int field, boolean preFlushing) {
> -        OpenJPAStateManager sm = this;
> -        while (sm.isEmbedded())
> -            sm = sm.getOwner();
> -        if (!sm.isNew() || sm.isFlushed() || sm.isDeleted())
> -            return false;
> -
> -        // special-case oid fields, which require us to look inside  
> the oid
> -        // object
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (fmd.getDeclaredTypeCode() == JavaTypes.OID) {
> -            // try to shortcut if possible
> -            if (_oid != null || isEmbedded() || !isPersistent())
> -                return true;
> -
> -            // check embedded fields of oid for value strategy +  
> default value
> -            FieldMetaData[] pks =  
> fmd.getEmbeddedMetaData().getFields();
> -            OpenJPAStateManager oidsm = null;
> -            boolean assign = false;
> -            for (int i = 0; !assign && i < pks.length; i++) {
> -                if (pks[i].getValueStrategy() ==  
> ValueStrategies.NONE)
> -                    continue;
> -                if (oidsm == null)
> -                    oidsm = new  
> ObjectIdStateManager(fetchObjectField(field),
> -                        this, fmd);
> -                assign = oidsm.isDefaultValue(i);
> -            }
> -            return assign && assignObjectId(!preFlushing,  
> preFlushing);
> -        }
> -
> -        // Just return if there's no value generation strategy
> -        if (fmd.getValueStrategy() == ValueStrategies.NONE)
> -            return false;
> -
> -        // Throw exception if field already has a value assigned.
> -        // @GeneratedValue overrides POJO initial values and setter  
> methods
> -        if (!fmd.isValueGenerated() && !isDefaultValue(field))
> -            throw new InvalidStateException(_loc.get(
> -                "existing-value-override-excep",  
> fmd.getFullName(false)));
> -
> -        // for primary key fields, assign the object id and recache  
> so that
> -        // to the user, so it looks like the oid always matches the  
> pk fields
> -        if (fmd.isPrimaryKey() && !isEmbedded())
> -            return assignObjectId(!preFlushing, preFlushing);
> -
> -        // for other fields just assign the field or flush if needed
> -        if (_broker.getStoreManager().assignField(this, field,  
> preFlushing)) {
> -            fmd.setValueGenerated(true);
> -            return true;
> -        }
> -        if (!preFlushing)
> -            _broker.flush();
> -        return !preFlushing;
> -    }
> -
> -    public Object getLock() {
> -        return _lock;
> -    }
> -
> -    public void setLock(Object lock) {
> -        _lock = lock;
> -    }
> -
> -    public Object getVersion() {
> -        return _version;
> -    }
> -
> -    public void setVersion(Object version) {
> -        _loadVersion = version;
> -        assignVersionField(version);
> -    }
> -
> -    Object getLoadVersion() {
> -        return _loadVersion;
> -    }
> -
> -    public void setNextVersion(Object version) {
> -        assignVersionField(version);
> -    }
> -
> -    private void assignVersionField(Object version) {
> -        _version = version;
> -        FieldMetaData vfield = _meta.getVersionField();
> -        if (vfield != null)
> -            store(vfield.getIndex(), JavaTypes.convert(version,
> -                vfield.getTypeCode()));
> -    }
> -
> -    public PCState getPCState() {
> -        return _state;
> -    }
> -
> -    public synchronized Object getImplData() {
> -        return _impl;
> -    }
> -
> -    public synchronized Object setImplData(Object data, boolean  
> cacheable) {
> -        Object old = _impl;
> -        _impl = data;
> -        if (cacheable && data != null)
> -            _flags |= FLAG_IMPL_CACHE;
> -        else
> -            _flags &= ~FLAG_IMPL_CACHE;
> -        return old;
> -    }
> -
> -    public boolean isImplDataCacheable() {
> -        return (_flags & FLAG_IMPL_CACHE) != 0;
> -    }
> -
> -    public Object getImplData(int field) {
> -        return getExtraFieldData(field, true);
> -    }
> -
> -    public Object setImplData(int field, Object data) {
> -        return setExtraFieldData(field, data, true);
> -    }
> -
> -    public synchronized boolean isImplDataCacheable(int field) {
> -        if (_fieldImpl == null || !_loaded.get(field))
> -            return false;
> -        if (_meta.getField(field).usesImplData() != null)
> -            return false;
> -        int idx = _meta.getExtraFieldDataIndex(field);
> -        return idx != -1 && _fieldImpl[idx] != null;
> -    }
> -
> -    public Object getIntermediate(int field) {
> -        return getExtraFieldData(field, false);
> -    }
> -
> -    public void setIntermediate(int field, Object data) {
> -        setExtraFieldData(field, data, false);
> -    }
> -
> -    /**
> -     * Return the data from the proper index of the extra field  
> data array.
> -     */
> -    private synchronized Object getExtraFieldData(int field,  
> boolean isLoaded) {
> -        // only return the field data if the field is in the right  
> loaded
> -        // state; otherwise we might return intermediate for impl  
> data or
> -        // vice versa
> -        if (_fieldImpl == null || _loaded.get(field) != isLoaded)
> -            return null;
> -        int idx = _meta.getExtraFieldDataIndex(field);
> -        return (idx == -1) ? null : _fieldImpl[idx];
> -    }
> -
> -    /**
> -     * Set the data from to proper index of the extra field data  
> array.
> -     */
> -    private synchronized Object setExtraFieldData(int field, Object  
> data,
> -        boolean loaded) {
> -        int idx = _meta.getExtraFieldDataIndex(field);
> -        if (idx == -1)
> -            throw new  
> InternalException(String.valueOf(_meta.getField(field)));
> -
> -        Object old = (_fieldImpl == null) ? null : _fieldImpl[idx];
> -        if (data != null) {
> -            // cannot set if field in wrong loaded state
> -            if (_loaded.get(field) != loaded)
> -                throw new  
> InternalException(String.valueOf(_meta.getField
> -                    (field)));
> -
> -            // set data
> -            if (_fieldImpl == null)
> -                _fieldImpl = new  
> Object[_meta.getExtraFieldDataLength()];
> -            _fieldImpl[idx] = data;
> -        } else if (_fieldImpl != null && _loaded.get(field) ==  
> loaded)
> -            _fieldImpl[idx] = null;
> -        return old;
> -    }
> -
> -    public Object fetch(int field) {
> -        Object val = fetchField(field, false);
> -        return _meta.getField(field).getExternalValue(val, _broker);
> -    }
> -
> -    public Object fetchField(int field, boolean transitions) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (fmd == null)
> -            throw new UserException(_loc.get("no-field",
> -                String.valueOf(field),  
> getManagedInstance().getClass())).
> -                setFailedObject(getManagedInstance());
> -
> -        // do normal state transitions
> -        if (!fmd.isPrimaryKey() && transitions)
> -            accessingField(field);
> -
> -        switch (fmd.getDeclaredTypeCode()) {
> -            case JavaTypes.STRING:
> -                return fetchStringField(field);
> -            case JavaTypes.OBJECT:
> -                return fetchObjectField(field);
> -            case JavaTypes.BOOLEAN:
> -                return (fetchBooleanField(field)) ? Boolean.TRUE
> -                    : Boolean.FALSE;
> -            case JavaTypes.BYTE:
> -                return new Byte(fetchByteField(field));
> -            case JavaTypes.CHAR:
> -                return new Character(fetchCharField(field));
> -            case JavaTypes.DOUBLE:
> -                return new Double(fetchDoubleField(field));
> -            case JavaTypes.FLOAT:
> -                return new Float(fetchFloatField(field));
> -            case JavaTypes.INT:
> -                return Numbers.valueOf(fetchIntField(field));
> -            case JavaTypes.LONG:
> -                return Numbers.valueOf(fetchLongField(field));
> -            case JavaTypes.SHORT:
> -                return new Short(fetchShortField(field));
> -            default:
> -                return fetchObjectField(field);
> -        }
> -    }
> -
> -    public void store(int field, Object val) {
> -        val = _meta.getField(field).getFieldValue(val, _broker);
> -        storeField(field, val);
> -    }
> -
> -    public void storeField(int field, Object val) {
> -        storeField(field, val, this);
> -    }
> -
> -    /**
> -     * <p>Checks whether or not <code>_pc</code> is dirty. In the  
> cases where
> -     * field tracking is not happening (see below), this method  
> will do a
> -     * state comparison to find whether <code>_pc</code> is dirty,  
> and will
> -     * update this instance with this information. In the cases  
> where field
> -     * tracking is happening, this method is a no-op.</p>
> -     *
> -     * <p>Fields are tracked for all classes that are run through  
> the OpenJPA
> -     * enhancer prior to or during deployment, and all classes  
> (enhanced or
> -     * unenhanced) in a Java 6 environment or newer.</p>
> -     *
> -     * <p>In a Java 5 VM or older:
> -     * <br>- instances of unenhanced classes that use
> -     * property access and obey the property access limitations are  
> tracked
> -     * when the instances are loaded from the database by OpenJPA,  
> and are
> -     * not tracked when the instances are created by application  
> code.
> -     * <br>- instances of unenhanced classes that use field access  
> are
> -     * never tracked.</p>
> -     *
> -     * @since 1.0.0
> -     */
> -    public void dirtyCheck() {
> -        if (!needsDirtyCheck())
> -            return;
> -
> -        SaveFieldManager saved = getSaveFieldManager();
> -        if (saved == null)
> -            throw new InternalException(_loc.get("no-saved-fields",
> -                getMetaData().getDescribedType().getName()));
> -
> -        FieldMetaData[] fmds = getMetaData().getFields();
> -        for (int i = 0; i < fmds.length; i++) {
> -            // pk and version fields cannot be mutated; don't mark  
> them
> -            // as such. ##### validate?
> -            if (!fmds[i].isPrimaryKey() && !fmds[i].isVersion()
> -                && _loaded.get(i)) {
> -                if (!saved.isFieldEqual(i, fetch(i))) {
> -                    dirty(i);
> -                }
> -            }
> -        }
> -    }
> -
> -    private boolean needsDirtyCheck() {
> -        if (isIntercepting())
> -            return false;
> -        if (isDeleted())
> -            return false;
> -        if (isNew() && !isFlushed())
> -            return false;
> -        return true;
> -    }
> -
> -    public Object fetchInitialField(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (_broker.getRestoreState() == RestoreState.RESTORE_NONE
> -            && ((_flags & FLAG_INVERSES) == 0
> -            || fmd.getInverseMetaDatas().length == 0))
> -            throw new InvalidStateException(_loc.get("restore- 
> unset"));
> -
> -        switch (fmd.getDeclaredTypeCode()) {
> -            case JavaTypes.DATE:
> -            case JavaTypes.CALENDAR:
> -            case JavaTypes.ARRAY:
> -            case JavaTypes.COLLECTION:
> -            case JavaTypes.MAP:
> -            case JavaTypes.OBJECT:
> -                // if we're not saving mutable types, throw an  
> exception
> -                if (_broker.getRestoreState() !=  
> RestoreState.RESTORE_ALL
> -                    && ((_flags & FLAG_INVERSES) == 0
> -                    || fmd.getInverseMetaDatas().length == 0))
> -                    throw new InvalidStateException(_loc.get
> -                        ("mutable-restore-unset"));
> -        }
> -
> -        lock();
> -        try {
> -            if (_saved == null || !_loaded.get(field) || ! 
> _dirty.get(field))
> -                return fetchField(field, false);
> -
> -            // if the field is dirty but we never loaded it, we  
> can't restore it
> -            if (_saved.getUnloaded().get(field))
> -                throw new InvalidStateException(_loc.get("initial- 
> unloaded",
> -                    fmd));
> -
> -            provideField(_saved.getState(), _single, field);
> -            return fetchField(_single, fmd);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    /**
> -     * Fetch the specified field from the specified field manager,  
> wrapping it
> -     * in an object if it's a primitive. A field should be provided  
> to the
> -     * field manager before this call is made.
> -     */
> -    private static Object fetchField(FieldManager fm, FieldMetaData  
> fmd) {
> -        int field = fmd.getIndex();
> -        switch (fmd.getDeclaredTypeCode()) {
> -            case JavaTypes.BOOLEAN:
> -                return (fm.fetchBooleanField(field)) ? Boolean.TRUE
> -                    : Boolean.FALSE;
> -            case JavaTypes.BYTE:
> -                return new Byte(fm.fetchByteField(field));
> -            case JavaTypes.CHAR:
> -                return new Character(fm.fetchCharField(field));
> -            case JavaTypes.DOUBLE:
> -                return new Double(fm.fetchDoubleField(field));
> -            case JavaTypes.FLOAT:
> -                return new Float(fm.fetchFloatField(field));
> -            case JavaTypes.INT:
> -                return Numbers.valueOf(fm.fetchIntField(field));
> -            case JavaTypes.LONG:
> -                return Numbers.valueOf(fm.fetchLongField(field));
> -            case JavaTypes.SHORT:
> -                return new Short(fm.fetchShortField(field));
> -            case JavaTypes.STRING:
> -                return fm.fetchStringField(field);
> -            default:
> -                return fm.fetchObjectField(field);
> -        }
> -    }
> -
> -    public void setRemote(int field, Object value) {
> -        lock();
> -        try {
> -            Boolean stat = dirty(field, Boolean.FALSE, false);
> -            storeField(field, value, _single);
> -            replaceField(_pc, _single, field);
> -            postDirty(stat);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    ////////////////////////
> -    // Lifecycle operations
> -    ////////////////////////
> -
> -    /**
> -     * Notification that the object is about to be accessed.
> -     *
> -     * @param field the field number being read, or -1 if not a  
> single
> -     * field read
> -     */
> -    void beforeRead(int field) {
> -        // allow unmediated reads of primary key fields
> -        if (field != -1 && _meta.getField(field).isPrimaryKey())
> -            return;
> -
> -        if (_broker.isActive() && !_broker.isTransactionEnding()) {
> -            if (_broker.getOptimistic())
> -                setPCState(_state.beforeOptimisticRead(this, field));
> -            else
> -                setPCState(_state.beforeRead(this, field));
> -        } else if (_broker.getNontransactionalRead())
> -            setPCState(_state.beforeNontransactionalRead(this,  
> field));
> -        else
> -            throw new InvalidStateException(_loc.get("non-trans- 
> read")).
> -                setFailedObject(getManagedInstance());
> -    }
> -
> -    /**
> -     * Delegates to the current state.
> -     *
> -     * @see PCState#beforeFlush
> -     */
> -    void beforeFlush(int reason, OpCallbacks call) {
> -        _state.beforeFlush(this, reason ==  
> BrokerImpl.FLUSH_LOGICAL, call);
> -    }
> -
> -    /**
> -     * Delegates to the current state.
> -     *
> -     * @see PCState#flush
> -     */
> -    void afterFlush(int reason) {
> -        // nothing happens when we flush non-persistent states
> -        if (!isPersistent())
> -            return;
> -
> -        if (reason != BrokerImpl.FLUSH_ROLLBACK
> -            && reason != BrokerImpl.FLUSH_LOGICAL) {
> -            // analyze previous state for later
> -            boolean wasNew = isNew();
> -            boolean wasFlushed = isFlushed();
> -            boolean wasDeleted = isDeleted();
> -
> -            // all dirty fields were flushed
> -            _flush.or(_dirty);
> -
> -            // important to set flushed bit after calling  
> _state.flush so
> -            // that the state can tell whether this is the first  
> flush
> -            setPCState(_state.flush(this));
> -            _flags |= FLAG_FLUSHED;
> -            _flags &= ~FLAG_FLUSHED_DIRTY;
> -
> -            _flags &= ~FLAG_VERSION_CHECK;
> -            _flags &= ~FLAG_VERSION_UPDATE;
> -
> -            // if this was an inc flush during which we had our  
> identity
> -            // assigned, tell the broker to cache us under our  
> final oid
> -            if (reason == BrokerImpl.FLUSH_INC)
> -                assertObjectIdAssigned(true);
> -
> -            // if this object was stored with preFlush, do post- 
> store callback
> -            if ((_flags & FLAG_PRE_FLUSHED) > 0)
> -                fireLifecycleEvent(LifecycleEvent.AFTER_STORE);
> -
> -            // do post-update as needed
> -            if (wasNew && !wasFlushed)
> -                 
> fireLifecycleEvent(LifecycleEvent.AFTER_PERSIST_PERFORMED);
> -            else if (wasDeleted)
> -                 
> fireLifecycleEvent(LifecycleEvent.AFTER_DELETE_PERFORMED);
> -            else
> -                // updates and new-flushed with changes
> -                 
> fireLifecycleEvent(LifecycleEvent.AFTER_UPDATE_PERFORMED);
> -        } else if (reason == BrokerImpl.FLUSH_ROLLBACK) {
> -            // revert to last loaded version and original oid
> -            assignVersionField(_loadVersion);
> -            if (isNew() && (_flags & FLAG_OID_ASSIGNED) == 0)
> -                _oid = null;
> -        }
> -        _flags &= ~FLAG_PRE_FLUSHED;
> -    }
> -
> -    /**
> -     * Delegates to the current state after checking the value
> -     * of the RetainState flag.
> -     *
> -     * @see PCState#commit
> -     * @see PCState#commitRetain
> -     */
> -    void commit() {
> -        // release locks before oid updated
> -        releaseLocks();
> -
> -        // update version and oid information
> -        setVersion(_version);
> -        _flags &= ~FLAG_FLUSHED;
> -        _flags &= ~FLAG_FLUSHED_DIRTY;
> -
> -        Object orig = _id;
> -        assertObjectIdAssigned(false);
> -
> -        boolean wasNew = isNew() && !isDeleted() && !isProvisional();
> -        if (_broker.getRetainState())
> -            setPCState(_state.commitRetain(this));
> -        else
> -            setPCState(_state.commit(this));
> -
> -        // ask the broker to re-cache us if we were new previously
> -        if (wasNew)
> -            _broker.setStateManager(orig, this,  
> BrokerImpl.STATUS_COMMIT_NEW);
> -    }
> -
> -    /**
> -     * Delegates to the current state after checking the value
> -     * of the RetainState flag.
> -     *
> -     * @see PCState#rollback
> -     * @see PCState#rollbackRestore
> -     */
> -    void rollback() {
> -        // release locks
> -        releaseLocks();
> -        _flags &= ~FLAG_FLUSHED;
> -        _flags &= ~FLAG_FLUSHED_DIRTY;
> -        afterFlush(BrokerImpl.FLUSH_ROLLBACK);
> -
> -        if (_broker.getRestoreState() != RestoreState.RESTORE_NONE)
> -            setPCState(_state.rollbackRestore(this));
> -        else
> -            setPCState(_state.rollback(this));
> -    }
> -
> -    /**
> -     * Rollback state of the managed instance to the given savepoint.
> -     */
> -    void rollbackToSavepoint(SavepointFieldManager savepoint) {
> -        _state = savepoint.getPCState();
> -        BitSet loaded = savepoint.getLoaded();
> -        for (int i = 0, len = loaded.length(); i < len; i++) {
> -            if (loaded.get(i) && savepoint.restoreField(i)) {
> -                provideField(savepoint.getCopy(), savepoint, i);
> -                replaceField(_pc, savepoint, i);
> -            }
> -        }
> -        _loaded = loaded;
> -        _dirty = savepoint.getDirty();
> -        _flush = savepoint.getFlushed();
> -        _version = savepoint.getVersion();
> -        _loadVersion = savepoint.getLoadVersion();
> -    }
> -
> -    /**
> -     * Delegates to the current state.
> -     *
> -     * @see PCState#persist
> -     * @see Broker#persist
> -     */
> -    void persist() {
> -        setPCState(_state.persist(this));
> -    }
> -
> -    /**
> -     * Delegates to the current state.
> -     *
> -     * @see PCState#delete
> -     * @see Broker#delete
> -     */
> -    void delete() {
> -        setPCState(_state.delete(this));
> -    }
> -
> -    /**
> -     * Delegates to the current state.
> -     *
> -     * @see PCState#nontransactional
> -     * @see Broker#nontransactional
> -     */
> -    void nontransactional() {
> -        setPCState(_state.nontransactional(this));
> -    }
> -
> -    /**
> -     * Delegates to the current state.
> -     *
> -     * @see PCState#transactional
> -     * @see Broker#transactional
> -     */
> -    void transactional() {
> -        setPCState(_state.transactional(this));
> -    }
> -
> -    /**
> -     * Delegates to the current state.
> -     *
> -     * @see PCState#nonprovisional
> -     */
> -    void nonprovisional(boolean logical, OpCallbacks call) {
> -        setPCState(_state.nonprovisional(this, logical, call));
> -    }
> -
> -    /**
> -     * Delegates to the current state.
> -     *
> -     * @see PCState#release
> -     * @see Broker#release
> -     */
> -    void release(boolean unproxy) {
> -        release(unproxy, false);
> -    }
> -
> -    void release(boolean unproxy, boolean force) {
> -        // optimization for detach-in-place special case when  
> fields are
> -        // already (un)proxied correctly
> -        if (!unproxy)
> -            _flags |= FLAG_NO_UNPROXY;
> -        try {
> -            if (force)
> -                setPCState(PCState.TRANSIENT);
> -            else
> -                setPCState(_state.release(this));
> -        } finally {
> -            _flags &= ~FLAG_NO_UNPROXY;
> -        }
> -    }
> -
> -    /**
> -     * Delegates to the current state.
> -     *
> -     * @see PCState#evict
> -     * @see Broker#evict
> -     */
> -    void evict() {
> -        setPCState(_state.evict(this));
> -    }
> -
> -    /**
> -     * Gather relations reachable from values using
> -     * {@link ValueMetaData#CASCADE_IMMEDIATE}.
> -     */
> -    void gatherCascadeRefresh(OpCallbacks call) {
> -        FieldMetaData[] fmds = _meta.getFields();
> -        for (int i = 0; i < fmds.length; i++) {
> -            if (!_loaded.get(i))
> -                continue;
> -
> -            if (fmds[i].getCascadeRefresh() ==  
> ValueMetaData.CASCADE_IMMEDIATE
> -                || fmds[i].getKey().getCascadeRefresh()
> -                == ValueMetaData.CASCADE_IMMEDIATE
> -                || fmds[i].getElement().getCascadeRefresh()
> -                == ValueMetaData.CASCADE_IMMEDIATE) {
> -                _single.storeObjectField(i, fetchField(i, false));
> -                _single.gatherCascadeRefresh(call);
> -                _single.clear();
> -            }
> -        }
> -    }
> -
> -    public boolean beforeRefresh(boolean refreshAll) {
> -        // note: all logic placed here rather than in the states for
> -        // optimization; this method public b/c used by remote  
> package
> -
> -        // nothing to do for non persistent or new unflushed  
> instances
> -        if (!isPersistent() || (isNew() && !isFlushed()))
> -            return false;
> -
> -        lock();
> -        try {
> -            // if dirty need to clear fields
> -            if (isDirty()) {
> -                clearFields();
> -                return true;
> -            }
> -
> -            // if some fields have been loaded but the instance is  
> out of
> -            // date or this is part of a refreshAll() and we don't  
> want to
> -            // take the extra hit to see if the instance is out of  
> date, clear
> -            if (_loaded.length() > 0 && (refreshAll || isEmbedded()
> -                || !syncVersion(null))) {
> -                Object version = _version;
> -                clearFields();
> -
> -                // if syncVersion just replaced the version, reset it
> -                if (!refreshAll && !isEmbedded())
> -                    setVersion(version);
> -                return true;
> -            }
> -            return false;
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    /**
> -     * Perform state transitions after refresh. This method is only
> -     * called if {@link #beforeRefresh} returns true.
> -     */
> -    void afterRefresh() {
> -        lock();
> -        try {
> -            // transition to clean or nontransactional depending on  
> trans status
> -            if (!_broker.isActive())
> -                setPCState(_state.afterNontransactionalRefresh());
> -            else if (_broker.getOptimistic())
> -                setPCState(_state.afterOptimisticRefresh());
> -            else
> -                setPCState(_state.afterRefresh());
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    /**
> -     * Mark this object as a dereferenced dependent object.
> -     */
> -    void setDereferencedDependent(boolean deref, boolean notify) {
> -        if (!deref && (_flags & FLAG_DEREF) > 0) {
> -            if (notify)
> -                _broker.removeDereferencedDependent(this);
> -            _flags &= ~FLAG_DEREF;
> -        } else if (deref && (_flags & FLAG_DEREF) == 0) {
> -            _flags |= FLAG_DEREF;
> -            if (notify)
> -                _broker.addDereferencedDependent(this);
> -        }
> -    }
> -
> -    ///////////
> -    // Locking
> -    ///////////
> -
> -    /**
> -     * Notification that we've been read-locked. Pass in the level  
> at which
> -     * we were locked and the level at which we should write lock  
> ourselves
> -     * on dirty.
> -     */
> -    void readLocked(int readLockLevel, int writeLockLevel) {
> -        // make sure object is added to transaction so lock will get
> -        // cleared on commit/rollback
> -        if (readLockLevel != LockLevels.LOCK_NONE)
> -            transactional();
> -
> -        _readLockLevel = readLockLevel;
> -        _writeLockLevel = writeLockLevel;
> -        _flags |= FLAG_READ_LOCKED;
> -        _flags &= ~FLAG_WRITE_LOCKED;
> -    }
> -
> -    /**
> -     * Return the lock level to use when loading state.
> -     */
> -    private int calculateLockLevel(boolean active, boolean forWrite,
> -        FetchConfiguration fetch) {
> -        if (!active)
> -            return LockLevels.LOCK_NONE;
> -        if (fetch == null)
> -            fetch = _broker.getFetchConfiguration();
> -
> -        if (_readLockLevel == -1)
> -            _readLockLevel = fetch.getReadLockLevel();
> -        if (_writeLockLevel == -1)
> -            _writeLockLevel = fetch.getWriteLockLevel();
> -        return (forWrite) ? _writeLockLevel : _readLockLevel;
> -    }
> -
> -    /**
> -     * Make sure we're locked at the given level.
> -     */
> -    private void obtainLocks(boolean active, boolean forWrite, int  
> lockLevel,
> -        FetchConfiguration fetch, Object sdata) {
> -        if (!active)
> -            return;
> -
> -        // if we haven't been locked yet, lock now at the given level
> -        int flag = (forWrite) ? FLAG_WRITE_LOCKED : FLAG_READ_LOCKED;
> -        if ((_flags & flag) == 0) {
> -            // make sure object is added to transaction so lock  
> will get
> -            // cleared on commit/rollback
> -            if (lockLevel != LockLevels.LOCK_NONE)
> -                transactional();
> -
> -            if (fetch == null)
> -                fetch = _broker.getFetchConfiguration();
> -            _broker.getLockManager().lock(this, lockLevel,
> -                fetch.getLockTimeout(), sdata);
> -            _flags |= FLAG_READ_LOCKED;
> -            _flags |= flag;
> -        }
> -    }
> -
> -    /**
> -     * Release locks.
> -     */
> -    private void releaseLocks() {
> -        if (_lock != null)
> -            _broker.getLockManager().release(this);
> -        _readLockLevel = -1;
> -        _writeLockLevel = -1;
> -        _flags &= ~FLAG_READ_LOCKED;
> -        _flags &= ~FLAG_WRITE_LOCKED;
> -    }
> -
> -    ////////////////////////////////////////////
> -    // Implementation of StateManager interface
> -    ////////////////////////////////////////////
> -
> -    /**
> -     * @return whether or not unloaded fields should be closed.
> -     */
> -    public boolean serializing() {
> -        // if the broker is in the midst of a serialization, then  
> no special
> -        // handling should be performed on the instance, and no  
> subsequent
> -        // load should happen
> -        if (_broker.isSerializing())
> -            return false;
> -
> -        try {
> -            if (_meta.isDetachable())
> -                return DetachManager.preSerialize(this);
> -
> -            load(_broker.getFetchConfiguration(), LOAD_SERIALIZE,  
> null, null,
> -                false);
> -            return false;
> -        } catch (RuntimeException re) {
> -            throw translate(re);
> -        }
> -    }
> -
> -    public boolean writeDetached(ObjectOutput out)
> -        throws IOException {
> -        BitSet idxs = new BitSet(_meta.getFields().length);
> -        lock();
> -        try {
> -            boolean detsm = DetachManager.writeDetachedState(this,  
> out, idxs);
> -            if (detsm)
> -                _flags |= FLAG_DETACHING;
> -
> -            FieldMetaData[] fmds = _meta.getFields();
> -            for (int i = 0; i < fmds.length; i++) {
> -                if (fmds[i].isTransient())
> -                    continue;
> -                provideField(_pc, _single, i);
> -                _single.serialize(out, !idxs.get(i));
> -                _single.clear();
> -            }
> -            return true;
> -        } catch (RuntimeException re) {
> -            throw translate(re);
> -        } finally {
> -            _flags &= ~FLAG_DETACHING;
> -            unlock();
> -        }
> -    }
> -
> -    public void proxyDetachedDeserialized(int idx) {
> -        // we don't serialize state manager impls
> -        throw new InternalException();
> -    }
> -
> -    public boolean isTransactional() {
> -        // special case for TCLEAN, which we want to appear non- 
> trans to
> -        // internal code, but which publicly should be transactional
> -        return _state == PCState.TCLEAN || _state.isTransactional();
> -    }
> -
> -    public boolean isPendingTransactional() {
> -        return _state.isPendingTransactional();
> -    }
> -
> -    public boolean isProvisional() {
> -        return _state.isProvisional();
> -    }
> -
> -    public boolean isPersistent() {
> -        return _state.isPersistent();
> -    }
> -
> -    public boolean isNew() {
> -        return _state.isNew();
> -    }
> -
> -    public boolean isDeleted() {
> -        return _state.isDeleted();
> -    }
> -
> -    public boolean isDirty() {
> -        return _state.isDirty();
> -    }
> -
> -    public boolean isDetached() {
> -        return (_flags & FLAG_DETACHING) != 0;
> -    }
> -
> -    public Object getGenericContext() {
> -        return _broker;
> -    }
> -
> -    public Object fetchObjectId() {
> -        try {
> -            assignObjectId(true);
> -            if (_oid == null || !_broker.getConfiguration().
> -                getCompatibilityInstance().getCopyObjectIds())
> -                return _oid;
> -
> -            if (_meta.getIdentityType() ==  
> ClassMetaData.ID_DATASTORE)
> -                return  
> _broker.getStoreManager().copyDataStoreId(_oid, _meta);
> -            return ApplicationIds.copy(_oid, _meta);
> -        } catch (RuntimeException re) {
> -            throw translate(re);
> -        }
> -    }
> -
> -    public Object getPCPrimaryKey(Object oid, int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        Object pk = ApplicationIds.get(oid, fmd);
> -        if (pk == null)
> -            return null;
> -
> -        ClassMetaData relmeta = fmd.getDeclaredTypeMetaData();
> -        pk = ApplicationIds.wrap(relmeta, pk);
> -        if (relmeta.getIdentityType() == ClassMetaData.ID_DATASTORE
> -            && fmd.getObjectIdFieldTypeCode() == JavaTypes.LONG)
> -            pk = _broker.getStoreManager().newDataStoreId(pk,  
> relmeta);
> -        else if (relmeta.getIdentityType() ==  
> ClassMetaData.ID_APPLICATION
> -            && fmd.getObjectIdFieldType() !=  
> relmeta.getObjectIdType())
> -            pk = ApplicationIds.fromPKValues(new Object[] { pk },  
> relmeta);
> -        return _broker.find(pk, false, null);
> -    }
> -
> -    public byte replaceFlags() {
> -        // we always use load required so that we can detect when  
> objects
> -        // are touched for locking or making transactional
> -        return PersistenceCapable.LOAD_REQUIRED;
> -    }
> -
> -    public StateManager replaceStateManager(StateManager sm) {
> -        return sm;
> -    }
> -
> -    public void accessingField(int field) {
> -        // possibly change state
> -        try {
> -            beforeRead(field);
> -            beforeAccessField(field);
> -        } catch (RuntimeException re) {
> -            throw translate(re);
> -        }
> -    }
> -
> -    /**
> -     * Load the given field before access.
> -     */
> -    protected void beforeAccessField(int field) {
> -        lock();
> -        try {
> -            boolean active = _broker.isActive();
> -            int lockLevel = calculateLockLevel(active, false, null);
> -            if (!_loaded.get(field))
> -                loadField(field, lockLevel, false, true);
> -            else
> -                assignField(field, false);
> -            obtainLocks(active, false, lockLevel, null, null);
> -        } catch (RuntimeException re) {
> -            throw translate(re);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void dirty(String field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (fmd == null)
> -            throw translate(new UserException(_loc.get("no-field",  
> field,
> -                ImplHelper.getManagedInstance(_pc).getClass()))
> -                .setFailedObject(getManagedInstance()));
> -
> -        dirty(fmd.getIndex(), null, true);
> -    }
> -
> -    public void dirty(int field) {
> -        dirty(field, null, true);
> -    }
> -
> -    /**
> -     * Make the given field dirty.
> -     *
> -     * @param mutate if null, may be an SCO mutation; if true, is  
> certainly
> -     * a mutation (or at least treat as one)
> -     * @return {@link Boolean#FALSE} if this instance was already  
> dirty,
> -     * <code>null</code> if it was dirty but not since flush, and
> -     * {@link Boolean#TRUE} if it was not dirty
> -     */
> -    private Boolean dirty(int field, Boolean mutate, boolean  
> loadFetchGroup) {
> -        boolean locked = false;
> -        boolean newFlush = false;
> -        boolean clean = false;
> -        try {
> -            FieldMetaData fmd = _meta.getField(field);
> -            if (!isNew() || isFlushed()) {
> -                if (fmd.getUpdateStrategy() ==  
> UpdateStrategies.RESTRICT)
> -                    throw new InvalidStateException(_loc.get
> -                        ("update-restrict", fmd));
> -                if (fmd.getUpdateStrategy() ==  
> UpdateStrategies.IGNORE)
> -                    return Boolean.FALSE;
> -            }
> -
> -            if (isEmbedded()) {
> -                // notify owner of change
> -                _owner.dirty(_ownerIndex, Boolean.TRUE,  
> loadFetchGroup);
> -            }
> -
> -            // is this a direct mutation of an sco field?
> -            if (mutate == null) {
> -                switch (fmd.getDeclaredTypeCode()) {
> -                    case JavaTypes.COLLECTION:
> -                    case JavaTypes.MAP:
> -                    case JavaTypes.ARRAY:
> -                    case JavaTypes.DATE:
> -                    case JavaTypes.CALENDAR:
> -                    case JavaTypes.OBJECT:
> -                        mutate = Boolean.TRUE;
> -                        break;
> -                    case JavaTypes.PC:
> -                        mutate =
> -                            (fmd.isEmbedded()) ? Boolean.TRUE :  
> Boolean.FALSE;
> -                        break;
> -                    default:
> -                        mutate = Boolean.FALSE; // not sco
> -                }
> -            }
> -
> -            // possibly change state
> -            boolean active = _broker.isActive();
> -            clean = !_state.isDirty(); // intentional direct access
> -
> -            // fire event fast before state change.
> -            if (clean)
> -                fireLifecycleEvent(LifecycleEvent.BEFORE_DIRTY);
> -            if (active) {
> -                if (_broker.getOptimistic())
> -                    setPCState(_state.beforeOptimisticWrite(this,  
> field,
> -                        mutate.booleanValue()));
> -                else
> -                    setPCState(_state.beforeWrite(this, field,
> -                        mutate.booleanValue()));
> -            } else if (fmd.getManagement() ==  
> FieldMetaData.MANAGE_PERSISTENT) {
> -                if (isPersistent() && ! 
> _broker.getNontransactionalWrite())
> -                    throw new InvalidStateException(_loc.get
> -                        ("non-trans-write")).setFailedObject
> -                        (getManagedInstance());
> -
> -                setPCState(_state.beforeNontransactionalWrite(this,  
> field,
> -                    mutate.booleanValue()));
> -            }
> -
> -            if ((_flags & FLAG_FLUSHED) != 0) {
> -                newFlush = (_flags & FLAG_FLUSHED_DIRTY) == 0;
> -                _flags |= FLAG_FLUSHED_DIRTY;
> -            }
> -
> -            lock();
> -            locked = true;
> -
> -            // note that the field is in need of flushing again,  
> and tell the
> -            // broker too
> -            _flush.clear(field);
> -            _broker.setDirty(this, newFlush && !clean);
> -
> -            // save the field for rollback if needed
> -            saveField(field);
> -
> -            // dirty the field and mark loaded; load fetch group if  
> needed
> -            int lockLevel = calculateLockLevel(active, true, null);
> -            if (!_dirty.get(field)) {
> -                setLoaded(field, true);
> -                _dirty.set(field);
> -
> -                // make sure the field's fetch group is loaded
> -                if (loadFetchGroup && isPersistent()
> -                    && fmd.getManagement() == fmd.MANAGE_PERSISTENT)
> -                    loadField(field, lockLevel, true, true);
> -            }
> -            obtainLocks(active, true, lockLevel, null, null);
> -        } catch (RuntimeException re) {
> -            throw translate(re);
> -        } finally {
> -            if (locked)
> -                unlock();
> -        }
> -
> -        if (clean)
> -            return Boolean.TRUE;
> -        if (newFlush) {
> -            // this event can be fired later cause we're already  
> dirty.
> -            fireLifecycleEvent(LifecycleEvent.BEFORE_DIRTY_FLUSHED);
> -            return null;
> -        }
> -        return Boolean.FALSE;
> -    }
> -
> -    /**
> -     * Fire post-dirty events after field value changes.
> -     *
> -     * @param status return value from {@link #dirty(int, Boolean,  
> boolean)}
> -     */
> -    private void postDirty(Boolean status) {
> -        if (Boolean.TRUE.equals(status))
> -            fireLifecycleEvent(LifecycleEvent.AFTER_DIRTY);
> -        else if (status == null)
> -            fireLifecycleEvent(LifecycleEvent.AFTER_DIRTY_FLUSHED);
> -    }
> -
> -    public void removed(int field, Object removed, boolean key) {
> -        if (removed == null)
> -            return;
> -
> -        try {
> -            // dereference dependent fields, delete embedded
> -            FieldMetaData fmd = _meta.getField(field);
> -            ValueMetaData vmd = (key) ? fmd.getKey() :  
> fmd.getElement();
> -            if (vmd.isEmbeddedPC())
> -                _single.delete(vmd, removed, null);
> -            else if (vmd.getCascadeDelete() ==  
> ValueMetaData.CASCADE_AUTO)
> -                _single.dereferenceDependent(removed);
> -        } catch (RuntimeException re) {
> -            throw translate(re);
> -        }
> -    }
> -
> -    public Object newProxy(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            return newFieldProxy(field);
> -
> -        switch (fmd.getTypeCode()) {
> -            case JavaTypes.DATE:
> -                if (fmd.getDeclaredType() == java.sql.Date.class)
> -                    return new  
> java.sql.Date(System.currentTimeMillis());
> -                if (fmd.getDeclaredType() ==  
> java.sql.Timestamp.class)
> -                    return new  
> java.sql.Timestamp(System.currentTimeMillis());
> -                if (fmd.getDeclaredType() == java.sql.Time.class)
> -                    return new  
> java.sql.Time(System.currentTimeMillis());
> -                return new Date();
> -            case JavaTypes.CALENDAR:
> -                return Calendar.getInstance();
> -            case JavaTypes.COLLECTION:
> -                return new ArrayList();
> -            case JavaTypes.MAP:
> -                return new HashMap();
> -        }
> -        return null;
> -    }
> -
> -    public Object newFieldProxy(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        ProxyManager mgr = _broker.getConfiguration().
> -            getProxyManagerInstance();
> -        Object init = fmd.getInitializer();
> -
> -        switch (fmd.getDeclaredTypeCode()) {
> -            case JavaTypes.DATE:
> -                return mgr.newDateProxy(fmd.getDeclaredType());
> -            case JavaTypes.CALENDAR:
> -                return mgr.newCalendarProxy(fmd.getDeclaredType(),
> -                    init instanceof TimeZone ? (TimeZone) init :  
> null);
> -            case JavaTypes.COLLECTION:
> -                return mgr.newCollectionProxy(fmd.getProxyType(),
> -                    fmd.getElement().getDeclaredType(),
> -                    init instanceof Comparator ? (Comparator)  
> init : null);
> -            case JavaTypes.MAP:
> -                return mgr.newMapProxy(fmd.getProxyType(),
> -                    fmd.getKey().getDeclaredType(),
> -                    fmd.getElement().getDeclaredType(),
> -                    init instanceof Comparator ? (Comparator)  
> init : null);
> -        }
> -        return null;
> -    }
> -
> -    public boolean isDefaultValue(int field) {
> -        lock();
> -        try {
> -            _single.clear();
> -            provideField(_pc, _single, field);
> -            boolean ret = _single.isDefaultValue();
> -            _single.clear();
> -            return ret;
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    /////////////////////////////////////////////////////////
> -    // Record that the field is dirty (which might load DFG)
> -    /////////////////////////////////////////////////////////
> -
> -    public void settingBooleanField(PersistenceCapable pc, int field,
> -        boolean curVal, boolean newVal, int set) {
> -        if (set != SET_REMOTE) {
> -            if (newVal == curVal && _loaded.get(field))
> -                return;
> -            assertNoPrimaryKeyChange(field);
> -        }
> -
> -        lock();
> -        try {
> -            Boolean stat = dirty(field, Boolean.FALSE, set ==  
> SET_USER);
> -            _single.storeBooleanField(field, newVal);
> -            replaceField(pc, _single, field);
> -            postDirty(stat);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void settingByteField(PersistenceCapable pc, int field,
> -        byte curVal, byte newVal, int set) {
> -        if (set != SET_REMOTE) {
> -            if (newVal == curVal && _loaded.get(field))
> -                return;
> -            assertNoPrimaryKeyChange(field);
> -        }
> -
> -        lock();
> -        try {
> -            Boolean stat = dirty(field, Boolean.FALSE, set ==  
> SET_USER);
> -            _single.storeByteField(field, newVal);
> -            replaceField(pc, _single, field);
> -            postDirty(stat);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void settingCharField(PersistenceCapable pc, int field,
> -        char curVal, char newVal, int set) {
> -        if (set != SET_REMOTE) {
> -            if (newVal == curVal && _loaded.get(field))
> -                return;
> -            assertNoPrimaryKeyChange(field);
> -        }
> -
> -        lock();
> -        try {
> -            Boolean stat = dirty(field, Boolean.FALSE, set ==  
> SET_USER);
> -            _single.storeCharField(field, newVal);
> -            replaceField(pc, _single, field);
> -            postDirty(stat);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void settingDoubleField(PersistenceCapable pc, int field,
> -        double curVal, double newVal, int set) {
> -        if (set != SET_REMOTE) {
> -            if (newVal == curVal && _loaded.get(field))
> -                return;
> -            assertNoPrimaryKeyChange(field);
> -        }
> -
> -        lock();
> -        try {
> -            Boolean stat = dirty(field, Boolean.FALSE, set ==  
> SET_USER);
> -            _single.storeDoubleField(field, newVal);
> -            replaceField(pc, _single, field);
> -            postDirty(stat);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void settingFloatField(PersistenceCapable pc, int field,
> -        float curVal, float newVal, int set) {
> -        if (set != SET_REMOTE) {
> -            if (newVal == curVal && _loaded.get(field))
> -                return;
> -            assertNoPrimaryKeyChange(field);
> -        }
> -
> -        lock();
> -        try {
> -            Boolean stat = dirty(field, Boolean.FALSE, set ==  
> SET_USER);
> -            _single.storeFloatField(field, newVal);
> -            replaceField(pc, _single, field);
> -            postDirty(stat);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void settingIntField(PersistenceCapable pc, int field,
> -        int curVal, int newVal, int set) {
> -        if (set != SET_REMOTE) {
> -            if (newVal == curVal && _loaded.get(field))
> -                return;
> -            assertNoPrimaryKeyChange(field);
> -        }
> -
> -        lock();
> -        try {
> -            Boolean stat = dirty(field, Boolean.FALSE, set ==  
> SET_USER);
> -            _single.storeIntField(field, newVal);
> -            replaceField(pc, _single, field);
> -            postDirty(stat);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void settingLongField(PersistenceCapable pc, int field,
> -        long curVal, long newVal, int set) {
> -        if (set != SET_REMOTE) {
> -            if (newVal == curVal && _loaded.get(field))
> -                return;
> -            assertNoPrimaryKeyChange(field);
> -        }
> -
> -        lock();
> -        try {
> -            Boolean stat = dirty(field, Boolean.FALSE, set ==  
> SET_USER);
> -            _single.storeLongField(field, newVal);
> -            replaceField(pc, _single, field);
> -            postDirty(stat);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void settingObjectField(PersistenceCapable pc, int field,
> -        Object curVal, Object newVal, int set) {
> -        if (set != SET_REMOTE) {
> -            FieldMetaData fmd = _meta.getField(field);
> -            if (_loaded.get(field)) {
> -                if (newVal == curVal)
> -                    return;
> -
> -                // only compare new to old values if the comparison  
> is going to
> -                // be cheap -- don't compare collections, maps, UDTs
> -                switch (fmd.getDeclaredTypeCode()) {
> -                    case JavaTypes.ARRAY:
> -                    case JavaTypes.COLLECTION:
> -                    case JavaTypes.MAP:
> -                    case JavaTypes.PC:
> -                    case JavaTypes.PC_UNTYPED:
> -                        break;
> -                    default:
> -                        if (newVal != null && newVal.equals(curVal))
> -                            return;
> -                }
> -            } else {
> -                // if this is a dependent unloaded field, make sure  
> to load
> -                // it now
> -                if (fmd.getCascadeDelete() ==  
> ValueMetaData.CASCADE_AUTO
> -                    || fmd.getKey().getCascadeDelete()
> -                    == ValueMetaData.CASCADE_AUTO
> -                    || fmd.getElement().getCascadeDelete()
> -                    == ValueMetaData.CASCADE_AUTO)
> -                    curVal = fetchObjectField(field);
> -            }
> -
> -            assertNoPrimaryKeyChange(field);
> -            if (fmd.getDeclaredTypeCode() == JavaTypes.OID)
> -                assertNotManagedObjectId(newVal);
> -        }
> -
> -        lock();
> -        try {
> -            Boolean stat = dirty(field, Boolean.FALSE, set ==  
> SET_USER);
> -            if (set != SET_REMOTE) {
> -                _single.storeObjectField(field, curVal);
> -                _single.unproxy();
> -                _single.dereferenceDependent();
> -                _single.clear();
> -            }
> -            _single.storeObjectField(field, newVal);
> -            replaceField(pc, _single, field);
> -            postDirty(stat);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void settingShortField(PersistenceCapable pc, int field,
> -        short curVal, short newVal, int set) {
> -        if (set != SET_REMOTE) {
> -            if (newVal == curVal && _loaded.get(field))
> -                return;
> -            assertNoPrimaryKeyChange(field);
> -        }
> -
> -        lock();
> -        try {
> -            Boolean stat = dirty(field, Boolean.FALSE, set ==  
> SET_USER);
> -            _single.storeShortField(field, newVal);
> -            replaceField(pc, _single, field);
> -            postDirty(stat);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void settingStringField(PersistenceCapable pc, int field,
> -        String curVal, String newVal, int set) {
> -        if (set != SET_REMOTE) {
> -            if (StringUtils.equals(newVal, curVal) &&  
> _loaded.get(field))
> -                return;
> -            assertNoPrimaryKeyChange(field);
> -        }
> -
> -        lock();
> -        try {
> -            Boolean stat = dirty(field, Boolean.FALSE, set ==  
> SET_USER);
> -            _single.storeStringField(field, newVal);
> -            replaceField(pc, _single, field);
> -            postDirty(stat);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    /**
> -     * Disallows changing primary key fields for instances.
> -     */
> -    private void assertNoPrimaryKeyChange(int field) {
> -        if (_oid != null && _meta.getField(field).isPrimaryKey())
> -            throw translate(new InvalidStateException(_loc.get
> -                ("change- 
> identity")).setFailedObject(getManagedInstance()));
> -    }
> -
> -    /**
> -     * Disallows setting an object id field to a managed instance.
> -     */
> -    void assertNotManagedObjectId(Object val) {
> -        if (val != null
> -            && (ImplHelper.toPersistenceCapable(val,
> -                  
> getContext().getConfiguration())).pcGetGenericContext()!= null)
> -            throw translate(new InvalidStateException(_loc.get
> -                ("managed-oid", Exceptions.toString(val),
> -                    Exceptions.toString(getManagedInstance()))).
> -                setFailedObject(getManagedInstance()));
> -    }
> -
> -    ////////////////////////////
> -    // Delegate to FieldManager
> -    ////////////////////////////
> -
> -    public void providedBooleanField(PersistenceCapable pc, int  
> field,
> -        boolean curVal) {
> -        _fm.storeBooleanField(field, curVal);
> -    }
> -
> -    public void providedByteField(PersistenceCapable pc, int field,
> -        byte curVal) {
> -        _fm.storeByteField(field, curVal);
> -    }
> -
> -    public void providedCharField(PersistenceCapable pc, int field,
> -        char curVal) {
> -        _fm.storeCharField(field, curVal);
> -    }
> -
> -    public void providedDoubleField(PersistenceCapable pc, int field,
> -        double curVal) {
> -        _fm.storeDoubleField(field, curVal);
> -    }
> -
> -    public void providedFloatField(PersistenceCapable pc, int field,
> -        float curVal) {
> -        _fm.storeFloatField(field, curVal);
> -    }
> -
> -    public void providedIntField(PersistenceCapable pc, int field,
> -        int curVal) {
> -        _fm.storeIntField(field, curVal);
> -    }
> -
> -    public void providedLongField(PersistenceCapable pc, int field,
> -        long curVal) {
> -        _fm.storeLongField(field, curVal);
> -    }
> -
> -    public void providedObjectField(PersistenceCapable pc, int field,
> -        Object curVal) {
> -        _fm.storeObjectField(field, curVal);
> -    }
> -
> -    public void providedShortField(PersistenceCapable pc, int field,
> -        short curVal) {
> -        _fm.storeShortField(field, curVal);
> -    }
> -
> -    public void providedStringField(PersistenceCapable pc, int field,
> -        String curVal) {
> -        _fm.storeStringField(field, curVal);
> -    }
> -
> -    public boolean replaceBooleanField(PersistenceCapable pc, int  
> field) {
> -        return _fm.fetchBooleanField(field);
> -    }
> -
> -    public byte replaceByteField(PersistenceCapable pc, int field) {
> -        return _fm.fetchByteField(field);
> -    }
> -
> -    public char replaceCharField(PersistenceCapable pc, int field) {
> -        return _fm.fetchCharField(field);
> -    }
> -
> -    public double replaceDoubleField(PersistenceCapable pc, int  
> field) {
> -        return _fm.fetchDoubleField(field);
> -    }
> -
> -    public float replaceFloatField(PersistenceCapable pc, int  
> field) {
> -        return _fm.fetchFloatField(field);
> -    }
> -
> -    public int replaceIntField(PersistenceCapable pc, int field) {
> -        return _fm.fetchIntField(field);
> -    }
> -
> -    public long replaceLongField(PersistenceCapable pc, int field) {
> -        return _fm.fetchLongField(field);
> -    }
> -
> -    public Object replaceObjectField(PersistenceCapable pc, int  
> field) {
> -        return _fm.fetchObjectField(field);
> -    }
> -
> -    public short replaceShortField(PersistenceCapable pc, int  
> field) {
> -        return _fm.fetchShortField(field);
> -    }
> -
> -    public String replaceStringField(PersistenceCapable pc, int  
> field) {
> -        return _fm.fetchStringField(field);
> -    }
> -
> -    //////////////////////////////////
> -    // Implementation of FieldManager
> -    //////////////////////////////////
> -
> -    public boolean fetchBoolean(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            return fetchBooleanField(field);
> -
> -        Object val = fetchField(field, false);
> -        return ((Boolean) fmd.getExternalValue(val,  
> _broker)).booleanValue();
> -    }
> -
> -    public boolean fetchBooleanField(int field) {
> -        lock();
> -        try {
> -            if (!_loaded.get(field))
> -                loadField(field, LockLevels.LOCK_NONE, false, false);
> -
> -            provideField(_pc, _single, field);
> -            return _single.fetchBooleanField(field);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public byte fetchByte(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            return fetchByteField(field);
> -
> -        Object val = fetchField(field, false);
> -        return ((Number) fmd.getExternalValue(val,  
> _broker)).byteValue();
> -    }
> -
> -    public byte fetchByteField(int field) {
> -        lock();
> -        try {
> -            if (!_loaded.get(field))
> -                loadField(field, LockLevels.LOCK_NONE, false, false);
> -
> -            provideField(_pc, _single, field);
> -            return _single.fetchByteField(field);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public char fetchChar(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            return fetchCharField(field);
> -
> -        Object val = fetchField(field, false);
> -        return ((Character) fmd.getExternalValue(val,  
> _broker)).charValue();
> -    }
> -
> -    public char fetchCharField(int field) {
> -        lock();
> -        try {
> -            if (!_loaded.get(field))
> -                loadField(field, LockLevels.LOCK_NONE, false, false);
> -
> -            provideField(_pc, _single, field);
> -            return _single.fetchCharField(field);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public double fetchDouble(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            return fetchDoubleField(field);
> -
> -        Object val = fetchField(field, false);
> -        return ((Number) fmd.getExternalValue(val,  
> _broker)).doubleValue();
> -    }
> -
> -    public double fetchDoubleField(int field) {
> -        lock();
> -        try {
> -            if (!_loaded.get(field))
> -                loadField(field, LockLevels.LOCK_NONE, false, false);
> -
> -            provideField(_pc, _single, field);
> -            return _single.fetchDoubleField(field);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public float fetchFloat(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            return fetchFloatField(field);
> -
> -        Object val = fetchField(field, false);
> -        return ((Number) fmd.getExternalValue(val,  
> _broker)).floatValue();
> -    }
> -
> -    public float fetchFloatField(int field) {
> -        lock();
> -        try {
> -            if (!_loaded.get(field))
> -                loadField(field, LockLevels.LOCK_NONE, false, false);
> -
> -            provideField(_pc, _single, field);
> -            return _single.fetchFloatField(field);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public int fetchInt(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            return fetchIntField(field);
> -
> -        Object val = fetchField(field, false);
> -        return ((Number) fmd.getExternalValue(val,  
> _broker)).intValue();
> -    }
> -
> -    public int fetchIntField(int field) {
> -        lock();
> -        try {
> -            if (!_loaded.get(field))
> -                loadField(field, LockLevels.LOCK_NONE, false, false);
> -
> -            provideField(_pc, _single, field);
> -            return _single.fetchIntField(field);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public long fetchLong(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            return fetchLongField(field);
> -
> -        Object val = fetchField(field, false);
> -        return ((Number) fmd.getExternalValue(val,  
> _broker)).longValue();
> -    }
> -
> -    public long fetchLongField(int field) {
> -        lock();
> -        try {
> -            if (!_loaded.get(field))
> -                loadField(field, LockLevels.LOCK_NONE, false, false);
> -
> -            provideField(_pc, _single, field);
> -            return _single.fetchLongField(field);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public Object fetchObject(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            return fetchObjectField(field);
> -
> -        Object val = fetchField(field, false);
> -        return fmd.getExternalValue(val, _broker);
> -    }
> -
> -    public Object fetchObjectField(int field) {
> -        lock();
> -        try {
> -            if (!_loaded.get(field))
> -                loadField(field, LockLevels.LOCK_NONE, false, false);
> -
> -            provideField(_pc, _single, field);
> -            return _single.fetchObjectField(field);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public short fetchShort(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            return fetchShortField(field);
> -
> -        Object val = fetchField(field, false);
> -        return ((Number) fmd.getExternalValue(val,  
> _broker)).shortValue();
> -    }
> -
> -    public short fetchShortField(int field) {
> -        lock();
> -        try {
> -            if (!_loaded.get(field))
> -                loadField(field, LockLevels.LOCK_NONE, false, false);
> -
> -            provideField(_pc, _single, field);
> -            return _single.fetchShortField(field);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public String fetchString(int field) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            return fetchStringField(field);
> -
> -        Object val = fetchField(field, false);
> -        return (String) fmd.getExternalValue(val, _broker);
> -    }
> -
> -    public String fetchStringField(int field) {
> -        lock();
> -        try {
> -            if (!_loaded.get(field))
> -                loadField(field, LockLevels.LOCK_NONE, false, false);
> -
> -            provideField(_pc, _single, field);
> -            return _single.fetchStringField(field);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void storeBoolean(int field, boolean externalVal) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            storeBooleanField(field, externalVal);
> -        else {
> -            Object val = (externalVal) ? Boolean.TRUE :  
> Boolean.FALSE;
> -            storeField(field, fmd.getFieldValue(val, _broker));
> -        }
> -    }
> -
> -    public void storeBooleanField(int field, boolean curVal) {
> -        lock();
> -        try {
> -            _single.storeBooleanField(field, curVal);
> -            replaceField(_pc, _single, field);
> -            setLoaded(field, true);
> -            postLoad(field, null);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void storeByte(int field, byte externalVal) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            storeByteField(field, externalVal);
> -        else
> -            storeField(field, fmd.getFieldValue(new  
> Byte(externalVal),
> -                _broker));
> -    }
> -
> -    public void storeByteField(int field, byte curVal) {
> -        lock();
> -        try {
> -            _single.storeByteField(field, curVal);
> -            replaceField(_pc, _single, field);
> -            setLoaded(field, true);
> -            postLoad(field, null);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void storeChar(int field, char externalVal) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            storeCharField(field, externalVal);
> -        else
> -            storeField(field, fmd.getFieldValue(new  
> Character(externalVal),
> -                _broker));
> -    }
> -
> -    public void storeCharField(int field, char curVal) {
> -        lock();
> -        try {
> -            _single.storeCharField(field, curVal);
> -            replaceField(_pc, _single, field);
> -            setLoaded(field, true);
> -            postLoad(field, null);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void storeDouble(int field, double externalVal) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            storeDoubleField(field, externalVal);
> -        else
> -            storeField(field, fmd.getFieldValue(new  
> Double(externalVal),
> -                _broker));
> -    }
> -
> -    public void storeDoubleField(int field, double curVal) {
> -        lock();
> -        try {
> -            _single.storeDoubleField(field, curVal);
> -            replaceField(_pc, _single, field);
> -            setLoaded(field, true);
> -            postLoad(field, null);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void storeFloat(int field, float externalVal) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            storeFloatField(field, externalVal);
> -        else
> -            storeField(field, fmd.getFieldValue(new  
> Float(externalVal),
> -                _broker));
> -    }
> -
> -    public void storeFloatField(int field, float curVal) {
> -        lock();
> -        try {
> -            _single.storeFloatField(field, curVal);
> -            replaceField(_pc, _single, field);
> -            setLoaded(field, true);
> -            postLoad(field, null);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void storeInt(int field, int externalVal) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            storeIntField(field, externalVal);
> -        else
> -            storeField(field,  
> fmd.getFieldValue(Numbers.valueOf(externalVal),
> -                _broker));
> -    }
> -
> -    public void storeIntField(int field, int curVal) {
> -        lock();
> -        try {
> -            _single.storeIntField(field, curVal);
> -            replaceField(_pc, _single, field);
> -            setLoaded(field, true);
> -            postLoad(field, null);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void storeLong(int field, long externalVal) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            storeLongField(field, externalVal);
> -        else
> -            storeField(field,  
> fmd.getFieldValue(Numbers.valueOf(externalVal),
> -                _broker));
> -    }
> -
> -    public void storeLongField(int field, long curVal) {
> -        lock();
> -        try {
> -            _single.storeLongField(field, curVal);
> -            replaceField(_pc, _single, field);
> -            setLoaded(field, true);
> -            postLoad(field, null);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void storeObject(int field, Object externalVal) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        externalVal = fmd.order(externalVal);
> -        if (!fmd.isExternalized())
> -            storeObjectField(field, externalVal);
> -        else
> -            storeField(field, fmd.getFieldValue(externalVal,  
> _broker));
> -    }
> -
> -    public void storeObjectField(int field, Object curVal) {
> -        lock();
> -        try {
> -            _single.storeObjectField(field, curVal);
> -            _single.proxy(true, false);
> -            replaceField(_pc, _single, field);
> -            setLoaded(field, true);
> -            postLoad(field, null);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void storeShort(int field, short externalVal) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            storeShortField(field, externalVal);
> -        else
> -            storeField(field, fmd.getFieldValue(new  
> Short(externalVal),
> -                _broker));
> -    }
> -
> -    public void storeShortField(int field, short curVal) {
> -        lock();
> -        try {
> -            _single.storeShortField(field, curVal);
> -            replaceField(_pc, _single, field);
> -            setLoaded(field, true);
> -            postLoad(field, null);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    public void storeString(int field, String externalVal) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (!fmd.isExternalized())
> -            storeStringField(field, externalVal);
> -        else
> -            storeField(field, fmd.getFieldValue(externalVal,  
> _broker));
> -    }
> -
> -    public void storeStringField(int field, String curVal) {
> -        lock();
> -        try {
> -            _single.storeStringField(field, curVal);
> -            replaceField(_pc, _single, field);
> -            setLoaded(field, true);
> -            postLoad(field, null);
> -        } finally {
> -            unlock();
> -        }
> -    }
> -
> -    /**
> -     * Store the given field value into the given field manager.
> -     */
> -    private void storeField(int field, Object val, FieldManager fm) {
> -        FieldMetaData fmd = _meta.getField(field);
> -        if (fmd == null)
> -            throw new UserException(_loc.get("no-field-index",
> -                String.valueOf(field), _meta.getDescribedType())).
> -                setFailedObject(getManagedInstance());
> -
> -        switch (fmd.getDeclaredTypeCode()) {
> -            case JavaTypes.BOOLEAN:
> -                boolean bool = val != null && ((Boolean)  
> val).booleanValue();
> -                fm.storeBooleanField(field, bool);
> -                break;
> -            case JavaTypes.BYTE:
> -                byte b = (val == null) ? 0 : ((Number)  
> val).byteValue();
> -                fm.storeByteField(field, b);
> -                break;
> -            case JavaTypes.CHAR:
> -                char c = (val == null) ? 0 : ((Character)  
> val).charValue();
> -                fm.storeCharField(field, c);
> -                break;
> -            case JavaTypes.DOUBLE:
> -                double d = (val == null) ? 0 : ((Number)  
> val).doubleValue();
> -                fm.storeDoubleField(field, d);
> -                break;
> -            case JavaTypes.FLOAT:
> -                float f = (val == null) ? 0 : ((Number)  
> val).floatValue();
> -                fm.storeFloatField(field, f);
> -                break;
> -            case JavaTypes.INT:
> -                int i = (val == null) ? 0 : ((Number)  
> val).intValue();
> -                fm.storeIntField(field, i);
> -                break;
> -            case JavaTypes.LONG:
> -                long l = (val == null) ? 0 : ((Number)  
> val).longValue();
> -                fm.storeLongField(field, l);
> -                break;
> -            case JavaTypes.SHORT:
> -                short s = (val == null) ? 0 : ((Number)  
> val).shortValue();
> -                fm.storeShortField(field, s);
> -                break;
> -            case JavaTypes.STRING:
> -                fm.storeStringField(field, (String) val);
> -                break;
> -            default:
> -                fm.storeObjectField(field, val);
> -        }
> -    }
> -
> -    /////////////
> -    // Utilities
> -    /////////////
> -
> -    /**
> -     * Erase the fact that this instance has been flushed.
> -     */
> -    void eraseFlush() {
> -        _flags &= ~FLAG_FLUSHED;
> -        _flags &= ~FLAG_FLUSHED_DIRTY;
> -
> -        int fmds = _meta.getFields().length;
> -        for (int i = 0; i < fmds; i++)
> -            _flush.clear(i);
> -    }
> -
> -    /**
> -     * Records that all instance fields are/are not loaded.
> -     * Primary key and non-persistent fields are not affected.
> -     */
> -    void setLoaded(boolean val) {
> -        FieldMetaData[] fmds = _meta.getFields();
> -        for (int i = 0; i < fmds.length; i++) {
> -            if (!fmds[i].isPrimaryKey()
> -                && fmds[i].getManagement() ==  
> fmds[i].MANAGE_PERSISTENT)
> -                setLoaded(i, val);
> -        }
> -        if (!val) {
> -            _flags &= ~FLAG_LOADED;
> -            setDirty(false);
> -        } else
> -            _flags |= FLAG_LOADED;
> -    }
> -
> -    /**
> -     * Records that all instance fields are/are not dirty,
> -     * and changes the flags of the instance accordingly.
> -     */
>
> [... 3925 lines stripped ...]
>

Craig L Russell
Architect, Sun Java Enterprise System http://db.apache.org/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!