A common use case for an application running in a servlet or application server is to "detach" objects from all server resources, modify them, and then "attach" them again. For example, a servlet might store persistent data in a user session between a modification based on a series of web forms. Between each form request, the web container might decide to serialize the session, requiring that the stored persistent state be disassociated from any other resources. Similarly, a client/server application might transfer persistent objects to a client via serialization, allow the client to modify their state, and then have the client return the modified data in order to be saved. This is sometimes referred to as the data transfer object or value object pattern, and it allows fine-grained manipulation of data objects without incurring the overhead of multiple remote method invocations.
		JDO provides support for this pattern using detach
		APIs that allow you to detach a persistent instance.  You can then
		modify the detached instance offline, and attach the instance back 
		into a PersistenceManager - either the same one 
		that detached the instance or a new one - using 
		makePersistent, which applies the changes to
		the the datastore.  
		
		In order to be able to detach a persistent instance, the
		metadata for the class must declare that it is eligible for
		detachment using the detachable
		class attribute.  We described this attribute in 
		Section 5.3, “Class Element”.
		
| ![[Note]](img/note.gif) | Note | 
|---|---|
| 
			After changing the  | 
public Object detachCopy (Object pc); public Collection detachCopyAll (Collection pcs); public Object[] detachCopyAll (Object[] pcs);
Each detach method returns unmanaged copies of the given instances. The copy mechanism is similar to serialization, except that only currently-loaded fields are copied.
When serializing a detachable object, the serialized copy will be in the detached state automatically. You do not need to explicitly detach an object before serializing it.
		Whether through detachCopy or through 
		serialization, detaching a dirty instance causes
		the current transaction transaction to flush. This means that when 
		subsequently re-attaching the detached object, JDO assumes that the 
		transaction from which it was originally detached committed.  If 
		the transaction rolled back, then either the re-attachment process will 
		throw an exception, or the transaction in which you re-attach the 
		instance will fail on commit, just as if a normal optimistic conflict 
		was detected.
		
public boolean getDetachAllOnCommit (); public void setDetachAllOnCommit (boolean detach);
		Set the DetachAllOnCommit property to automatically
		detach the entire PersistenceManager cache on 
		commit.  Unlike the explicit detachCopy 
		methods, the implicit detach-on-commit occurs in-place.  Every instance
		in the PersistenceManager cache transitions to
		the detached state, then the cache is cleared.
		
| ![[Note]](img/note.gif) | Note | 
|---|---|
| Kodo offers many enhancements to JDO detachment functionality, including additional options for automatic detachment. See Section 11.1, “Detach and Attach” in the Reference Guide for details. | 
Example 8.4. Detaching and Attaching
This example demonstrates a common client/server scenario. The client requests objects and makes changes to them, while the server handles the object lookups and transactions.
// CLIENT:
// requests an object with a given oid
Record detached = (Record) getFromServer (oid);
...
// SERVER:
// detaches object and returns to client
Object oid = processClientRequest ();
PersistenceManager pm = pmf.getPersistenceManager ();
Record record = (Record) pm.getObjectById (oid);
// we detach explicitly because we want to close the PM before serializing
Record detached = (Record) pm.detachCopy (record);
pm.close ();
sendToClient (detached);
...
// CLIENT:
// makes some modifications and sends back to server
detached.setSomeField ("bar");
sendToServer (detached);
...
// SERVER:
// re-attaches the instance and commit the changes
Record modified = (Record) processClientRequest ();
PersistenceManager pm = pmf.getPersistenceManager ();
pm.currentTransaction ().begin ();
Record attached = (Record) pm.makePersistent (modified);
attached.setLastModified (System.currentTimeMillis ());
attached.setModifier (getClientIdentityCode ());
pm.currentTransaction ().commit ();
pm.close ();
|    |