Oracle TopLink Developer's Guide
10g Release 3 (10.1.3) B13593-01 |
|
![]() Previous |
![]() Next |
The unit of work provides the following object registration options:
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.
This section examines how to use the registerNewObject
method, including the following the following:
Note: You cannot useUnitOfWork 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".
|
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.
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();
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 useUnitOfWork 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();
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:
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.
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.
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.
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".
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).