Skip Headers

# Avoiding the Use of Post-Commit Clones

Previous

Next

A common unit of work error is holding on to clones after commit time. Typically the clones are stored in a static variable and the developer incorrectly believes that this object is the cache copy. This leads to problems when another unit of work makes changes to the object and what the developer believes is the cache copy is not updated (because a unit of work updates only the cache copy, not old clones).

Consider the error in Example: Incorrect Use of Handle to Clone. In this example you get a handle to the cache copy of a `Pet` and store it in the static `CACHE_PET`. We get a handle to a working copy clone and store it in the static `CLONE_PET`. In a future unit of work, the `Pet` is changed.

Developers who incorrectly store global references to clones from units of work often expect them to be updated when the cache object is changed in a future unit of work. Only the cache copy is updated.

Incorrect Use of Handle to Clone

    // Read a Pet from the database, store in static
    CACHE_PET = (Pet)session.readObject(Pet.class);

    // Put a clone in a static.  This is a bad idea and is a common error
    UnitOfWork uow = session.acquireUnitOfWork();
        CLONE_PET = (Pet)uow.readObject(Pet.class);
        CLONE_PET.setName("Hairy");
    uow.commit();
    //Later, the pet is changed again
    UnitOfWork anotherUow = session.acquireUnitOfWork();
        Pet petClone = (Pet)anotherUow.registerObject(CACHE_PET);
        petClone.setName("Fuzzy");
    anotherUow.commit();

    // If you incorrectly stored the clone in a static and thought it should be
    // updated when it is later changed, you would be wrong: only the cache copy is
    // updated; NOT OLD CLONES
    System.out.println("CACHE_PET is" + CACHE_PET);
    System.out.println("CLONE_PET is" + CLONE_PET);

The two `System.out` calls produce the following output:

    CACHE_PET isPet type Cat named Fuzzy id:100
    CLONE_PET isPet type Cat named Hairy id:100