* to TRANSIENT. Used by "DetachAllOnCommit".
* @param state State for the detachment process
*/
public void detach(FetchPlanState state)
{
ApiAdapter api = myOM.getApiAdapter();
if (myLC.isDeleted() || api.isDetached(myPC) || detaching)
{
// Already deleted, detached or being detached
return;
}
// Check if detachable ... if so then we detach a copy, otherwise we return a transient copy
boolean detachable = api.isDetachable(myPC);
if (detachable)
{
if (JPOXLogger.PERSISTENCE.isDebugEnabled())
{
JPOXLogger.PERSISTENCE.debug(LOCALISER.msg("010009", StringUtils.toJVMIDString(myPC),
"" + state.getCurrentFetchDepth()));
}
// Call any "pre-detach" listeners
getCallbackHandler().preDetach(myPC);
}
try
{
detaching = true;
// Handle any field loading/unloading before the detach
if ((myOM.getFetchPlan().getDetachmentOptions() & FetchPlan.DETACH_LOAD_FIELDS) != 0)
{
// Load any unloaded fetch-plan fields
loadUnloadedFieldsInFetchPlan();
}
if ((myOM.getFetchPlan().getDetachmentOptions() & FetchPlan.DETACH_UNLOAD_FIELDS) != 0)
{
// Unload any loaded fetch-plan fields that aren't in the current fetch plan
unloadNonFetchPlanFields();
}
// Detach all (loaded) fields in the FetchPlan
FieldManager detachFieldManager = new DetachFieldManager(this, getSecondClassMutableFields(), myFP,
state, false);
for (int i = 0; i < loadedFields.length; i++)
{
if (loadedFields[i])
{
try
{
// Just fetch the field since we are usually called in postCommit() so dont want to update it
detachFieldManager.fetchObjectField(i);
}
catch (EndOfFetchPlanGraphException eofpge)
{
Object value = provideField(i);
if (api.isPersistable(value))
{
// PC field beyond end of graph
org.jpox.StateManager valueSM = myOM.findStateManager(value);
if (!api.isDetached(value) && !(valueSM != null && valueSM.isDetaching()))
{
// Field value is not detached or being detached so unload it
String fieldName = cmd.getMetaDataForManagedMemberAtAbsolutePosition(i).getName();
if (JPOXLogger.PERSISTENCE.isDebugEnabled())
{