11.2. Detachable behavior
Prev | Chapter 11. Detach and Attach | Next

## 11.2. Detachable behavior

The `KodoPersistenceManager` exposes six methods to support detach and attach functionality:

- `detach(Object ob)`

- `detachAll(Object[] obs)`

- `detachAll(Collection obs)`

- `attach(Object ob)`

- `attachAll(Object[] obs)`

- `attachAll(Collection obs)`

Detaching persistent instances will create unmanaged copies of the instances. The copy mechanism is similar to serialization, with the exception that only fields in the current fetch groups are traversed. Fields that are not in the current fetch groups will be set to the Java default for their type, and will be ignored when the detached instances are later re-attached. It is important to remember that invoking the `detach` method does not modify the persistent instance that is the parameter of the method call; it is the return value from that invocation that is the detached and unmanaged copy.

Example 11.1. Detaching a Single Instance

    import kodo.runtime.*;

    ...

    // CLIENT:
    // requests an object with a given oid
    DetachExample detached = (DetachExample) getFromServer (oid);

    ...

    // SERVER:
    // detaches object and returns to client
    Object oid = processClientRequest ();
    KodoPersistenceManager kpm = (KodoPersistenceManager) pm;
    DetachExample example = (DetachExample) kpm.getObjectById (oid, false);
    DetachExample detached = (DetachExample) kpm.detach (example);
    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
    DetachExample modified = (DetachExample) processClientRequest ();
    kpm.currentTransaction ().begin ();
    kpm.attach (modified);
    kpm.currentTransaction ().commit ();

If relation-type fields need to be detached, then they need to be declared as being in the `default-fetch-group`, or, if the capability is available, be declared in the custom fetch groups configuration for the `KodoPersistenceManager` performing the detachment.

Example 11.2. Using Custom Fetch Groups for Detach

    public class DetachExample
        implements java.io.Serializable
    {
        private String someField;
        private DetachExampleRelation someRelation;
    }

    <?xml version="1.0"?>
    <jdo>
      <package name="com.somecompany">
        <class name="DetachExample">
          <extension vendor-name="kodo" key="detachable" value="true"/>
          <field name="someRelation">
            <extension vendor-name="kodo" key="fetch-group" value="mygroup"/>
          </field>
        </class>
        <class name="DetachExampleRelation">
          <extension vendor-name="kodo" key="detachable" value="true"/>
        </class>
      </package>
    </jdo>

    import kodo.runtime.*;

    ...

    // CLIENT:
    // requests an object with a given oid
    DetachExample detached = (DetachExample) getFromServer (oid);

    ...

    // SERVER:
    // detaches object and returns to client
    Object oid = processClientRequest ();
    KodoPersistenceManager kpm = (KodoPersistenceManager) pm;
    kpm.getFetchConfiguration ().addFetchGroup ("mygroup");
    DetachExample example = (DetachExample) kpm.getObjectById (oid, false);
    DetachExample detached = (DetachExample) kpm.detach (example);
    sendToClient (detached);

    ...

    // CLIENT:
    // makes some modifications and sends back to server
    detached.setSomeField ("bar");
    detached.getRelation ().setSomeOtherField ("baz");
    sendToServer (detached);

    ...

    // SERVER:
    // re-attaches the instance and commit the changes
    DetachExample modified = (DetachExample) processClientRequest ();
    kpm.currentTransaction ().begin ();
    kpm.attach (modified); // will recursively attach relation too and apply mods
    kpm.currentTransaction ().commit ();

When attaching an instance whose representation has changed in the datastore since detachment, a `JDOOptimisticVerificationException` will be thrown upon commit or flush, just as if a normal optimistic conflict was detected. When attaching an instance that represents an object that has been deleted since detaching, or when a attaching a detached instance into a `PersistenceManager` that has an earlier version of the object, a `JDOOptimisticVerificationException` will be immediately thrown when `attach` is invoked. In these cases, the `RollbackOnly` flag will be set on the transaction.

Prev | Up | Next
Chapter 11. Detach and Attach | Home | 11.3. Detach and Attach Callbacks