assertIsPO(o, "detachCopy");
return speedoDetachCopy((PersistentObjectItf)o, new HashMap(), new ArrayList());
}
public Object speedoDetachCopy(PersistentObjectItf po, Map map, Collection fgHints){
JDOPersistentObjectItf jdopo = (JDOPersistentObjectItf) po;
//check the meta info about the detachability of the class
if(jdopo.jdoIsPersistent()){
if(jdopo.jdoIsDeleted()){
//persistent_deleted
if(!jdopo.jdoIsNew())
throw new JDOUserException("This object cannot be detached: it has been deleted from the datastore.");
}
}
else{
//makePersistent
speedoMakePersistent(jdopo, null);
}
if(!jdopo.speedoGetHome().isDetachable()){
throw new JDOUserException("This class cannot be detached: it has not been defined as detachable in the jdo file.");
}
jdopo.speedoGetHome().sendEvent(HomeItf.PRE_DETACH, jdopo, null);
//persistent_new or persistent_dirty: updated with object id and version
if(jdopo.jdoIsTransactional() && jdopo.jdoIsDirty()){
try{
StateItf sa = (StateItf) tpm.writeIntention(tx, jdopo, null);
if(!sa.hasBeenFlush()){
//flush
tpm.flush(tx, sa);
}
} catch (Exception e) {
throw new JDODataStoreException(
"Problem while flushing a persistent object in order to detach a copy.",
new Exception[]{ExceptionHelper.getNested(e)});
}
}
//the core processing
//avoid cycles using a map
try{
synchronized(fgHints){
PersistentObjectItf copy = jdopo.speedoGetHome().detachCopy(jdopo, this, map, null, fgHints);
if (jdopo.speedoGetHome().getVersioningStrategy() == SpeedoVersion.VERSION_NUMBER) {
copy.speedoGetReferenceState().speedoChangeVersion();
}
return copy;
}
}
catch(Exception e){
throw new JDOUserException("Detach cannot be performed", new Exception[]{ExceptionHelper.getNested(e)});
} finally {
jdopo.speedoGetHome().sendEvent(HomeItf.POST_DETACH, jdopo, null);
}
}