Skip Headers
Oracle TopLink Developer's Guide
10g Release 3 (10.1.3)
B13593-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

Registering and Unregistering Objects

The unit of work provides the following object registration options:

Creating and Registering an Object in One Step

Example 102-1 shows how to use the unit of work newInstance method to create a new Pet object, register it with the unit of work, and return a clone, all in one step. If you are using a factory design pattern to create your objects (and have specified this in the query builder), the newInstance method will use the appropriate factory.

Example 102-1 Creating and Registering an Object in One Step

UnitOfWork uow = session.acquireUnitOfWork();
    Pet petClone = (Pet)uow.newInstance(Pet.class);
    petClone.setId(100);
    petClone.setName("Fluffy");
    petClone.setType("Cat");
uow.commit();

Using registerNewObject

This section examines how to use the registerNewObject method, including the following the following:


Note:

You cannot use UnitOfWork methods registerObject, registerNewObject, or registerExistingObject with an aggregate object (see "Relational Aggregate Descriptors"). Doing so will raise a ValidationException or other errors at commit time. For more information, see "Working with Aggregates".

Registering a New Object with registerNewObject

The registerNewObject method registers a new object as if it was a clone. At commit time, the unit of work creates another instance of the object to be the cache version of that object.

Use registerNewObject in situations where:

  • You do not need a handle to the cache version of the object after the commit transaction and you do not want to work with clones of new objects.

  • You must pass a clone into the constructor of a new object, then register the new object.

Example 102-2 shows how to register a new object with the registerNewObject method.

Example 102-2 Registering a New Object with the registerNewObject Method

UnitOfWork uow = session.acquireUnitOfWork();
    PetOwner existingPetOwnerClone =
        PetOwner)uow.readObject(PetOwner.class);

    Pet newPet = new Pet();
    newPet.setId(900);
    newPet.setType("Lizzard");
    newPet.setName("Larry");
    newPet.setPetOwner(existingPetOwnerClone);

    uow.registerNewObject(newPet); 
uow.commit();

By using registerNewObject, the variable newPet should not be used after the unit of work is committed. The new object is the clone and if you need the cache version of the object, you need to query for it. If you needed a handle to the cache version of the Pet after the unit of work has been committed, then you should use the first approach described in "Associating a New Source to an Existing Target Object". In that example, the variable newPet is the cache version after the unit of work is committed.

Associating New Objects With One Another

At commit time, TopLink can determine if an object is new or not. As described in "Associating a New Target to an Existing Source Object", if a new object is reachable from a clone, you do not need to register it. TopLink effectively uses the registerNewObject method on all new objects it can reach from registered objects.

When working with new objects, remember the following rules:

  • Only reachable or registered objects will be persisted.

  • New objects or objects that have been registered with registerNewObject are considered to be working copies in the unit of work.

  • If you call registerObject with a new object, the clone, and the argument, is considered the cache version.

Example 102-3 shows how to associate new objects with the registerNewObject method.

Example 102-3 Associating New Objects with the registerNewObject Method

UnitOfWork uow = session.acquireUnitOfWork();
    Pet newPet = new Pet();
    newPet.setId(150);
    newPet.setType("Horse");
    newPet.setName("Ed");

    PetOwner newPetOwner = new PetOwner();
    newPetOwner.setId(250);
    newPetOwner.setName("George");
    newPetOwner.setPhoneNumber("555-9999");

    VetVisit newVetVisit = new VetVisit();
    newVetVisit.setId(350);
    newVetVisit.setNotes("Talks a lot");
    newVetVisit.setSymptoms("Sore throat");

    newPet.getVetVisits().addElement(newVetVisit);
    newVetVisit.setPet(newPet);
    newPet.setPetOwner(newPetOwner);

    uow.registerNewObject(newPet);
uow.commit();

However, after the unit of work commit, do not use the objects in the variables newPet, newPetOwner, and newVetVisit because they are technically copies from the unit of work.

If you need a handle to the cache version of these objects, query for them or use the unit of work as shown in Example 102-4.

Example 102-4 Associating New Objects with the newObjectMethod and Retaining a Handle to the Cache Objects

UnitOfWork uow = session.acquireUnitOfWork();
    Pet newPet = new Pet();
    Pet newPetClone = (Pet)uow.registerObject(newPet);
    newPetClone.setId(150);
    newPetClone.setType("Horse");
    newPetClone.setName("Ed");

    PetOwner newPetOwner = new PetOwner();
    PetOwner newPetOwnerClone = 
        (PetOwner)uow.registerObject(newPetOwner);
    newPetOwnerClone.setId(250);
    newPetOwnerClone.setName("George");
    newPetOwnerClone.setPhoneNumber("555-9999");

    VetVisit newVetVisit = new VetVisit();
    VetVisit newVetVisitClone = 
        (VetVisit)uow.registerObject(newVetVisit);
    newVetVisitClone.setId(350);
    newVetVisitClone.setNotes("Talks a lot");
    newVetVisitClone.setSymptoms("Sore throat");

    newPetClone.getVetVisits().addElement(newVetVisitClone);
    newVetVisitClone.setPet(newPetClone);
    newPetClone.setPetOwner(newPetOwnerClone);
uow.commit(); 

Using registerAllObjects

The registerAllObjects method takes a Collection of objects as an argument and returns a Collection of clones. This lets you register many objects at once as shown in Example 102-5.


Note:

You cannot use UnitOfWork methods registerObject, registerNewObject, or registerExistingObject with an aggregate object (see "Relational Aggregate Descriptors"). Doing so will raise a ValidationException or other errors at commit time. For more information, see "Working with Aggregates".

Example 102-5 Using registerAllObjects

UnitOfWork uow = session.acquireUnitOfWork();
    Collection toRegister = new Vector(2);
    VetVisit vv1 = new VetVisit();
    vv1.setId(70);
    vv1.setNotes("May have flu");
    vv1.setSymptoms("High temperature");
    toRegister.add(vv1);

    VetVisit vv2 = new VetVisit();
    vv2.setId(71);
    vv2.setNotes("May have flu");
    vv2.setSymptoms("Sick to stomach");
    toRegister.add(vv2);

    uow.registerAllObjects(toRegister);
uow.commit();

Using Registration and Existence Checking

When you register an object with the unit of work, TopLink runs an existence check to determine whether or not the object exists. TopLink uses this information at commit time to determine whether to perform an insert or an update operation. You can specify the default existence checking policy for a project as a whole (see "Configuring Existence Checking at the Project Level") or on a per-descriptor basis ("Configuring Cache Existence Checking at the Descriptor Level"). By default, TopLink uses the check cache existence checking policy. If you use any existence checking policy other than check cache, then you can use the way you register your objects to your advantage to reduce the time it takes TopLink to register an object.

This section explains how to use one of the following existence checking policies to accelerate object registration:

Check Database

If you configure a class's descriptor with an existence checking policy of check database, TopLink will check the database for existence for all instances of that class registered in a unit of work. However, if you know that an object is new or existing, rather than use the basic registerObject method, you can use registerNewObject or registerExistingObject to bypass the existence check. TopLink will not check the database for existence on objects that you have registered with these methods. It will automatically perform an insert operation if registerNewObject is called, or an update operation if registerExistingObject is called.

Assume Existence

If you configure a class's descriptor with an existence checking policy of assume existence, TopLink will assume that all instances of that class registered with a unit of work exist and TopLink will always perform an update operation to the database on all such registered objects; even new objects that you registered with registerObject method. However, if you use the registerNewObject method on the new object, TopLink knows to perform an insert operation in the database even though the existence checking policy says assume existence.

Assume Nonexistence

If you configure a class's descriptor with an existence checking policy of assume nonexistence then TopLink assumes that all instances of that class registered with a unit of work do not exist and will always perform an insert operation on the database, even on objects read from the database. However, if you use the registerExistingObject method on existing objects, TopLink knows to perform an update operation on the database.

Working with Aggregates

Aggregate mapped objects should never be registered in a TopLink unit of work–doing so will generate an exception. Aggregate cloning and registration is automatic based on the owner of the aggregate object. In other words, if you register the owner of an aggregate, the aggregate is automatically cloned. When you get a working copy of an aggregate owner, its aggregate is also a working copy.

When working with aggregates, you should always use an aggregate within the context of its owner:

  • If you get an aggregate from a working clone owner, then the aggregate is a working clone.

  • If you get an aggregate from a cache version owner, then the aggregate is the cache version.

For more information about aggregate objects, see "Relational Aggregate Descriptors".

Unregistering Working Clones

The unit of work unregisterObject method lets you unregister a previously registered object from a unit of work. An unregistered object will be ignored in the unit of work, and any uncommitted changes made to the object up to that point will be discarded.

In general, this method is rarely used. It can be useful if you create a new object, but then decide to delete it in the same unit of work (which is not recommended).