Oracle TopLink Developer's Guide
10g Release 3 (10.1.3) B13593-01 |
|
![]() Previous |
![]() Next |
"Deleting Objects" explained that TopLink always properly arranges (orders) the SQL based on the mappings and foreign keys in your object model and schema. You can control the order of delete operations by the following:
By default, TopLink does insert and update operations first, before delete operations, to ensure that referential integrity is maintained. This is the preferred approach.
If you are forced to replace an object with unique constraints by deleting it and inserting a replacement, you may cause a constraint violation if the insert operation occurs before the delete operation. In this case, call setShouldPerformDeletesFirst
to perform the delete operation before the insert operation.
The constraints used by TopLink to determine delete order are inferred from one-to-one and one-to-many mappings. If you do not have such mappings, you can add constraint knowledge to TopLink using the descriptor addConstraintDependencies(Class)
method.
For example, suppose you have a composition of objects: A contains B (one-to-many, privately owned) and B has a one-to-one, nonprivate relationship with C. You want to delete A (and in doing so the included Bs) but before deleting the Bs, for some of them (not all) you want to delete the associated object C.
There are two possible solutions:
In the first option, you do not identify the one-to-many (A to B) relationship as privately owned. When deleting an A object, you must delete all of its B objects, as well as any C objects, as shown in the following example:
uow.deleteObject(existingA);
uow.deleteAllObjects(existingA.getBs());
// delete one of the Cs
uow.deleteObject(((B) existingA.getBs().get(1)).getC());
This option produces the following SQL:
DELETE FROM B WHERE (ID = 2) DELETE FROM B WHERE (ID = 1) DELETE FROM A WHERE (ID = 1) DELETE FROM C WHERE (ID = 1)
In the second option, keep the one-to-many (A to B) relationship privately owned and add a constraint dependency from A to C, as shown in the following example:
session.getDescriptor(A.class).addConstraintDependencies(C.class);
Now the delete code would be:
uow.deleteObject(existingA);
// delete one of the Cs
uow.deleteObject(((B) existingA.getBs().get(1)).getC());
This option produces the following SQL:
DELETE FROM B WHERE (A = 1) DELETE FROM A WHERE (ID = 1) DELETE FROM C WHERE (ID = 1)
In both cases, the B object is deleted before A and C. The main difference is that the second option generates fewer SQL statements, as it knows that it is deleting the entire set of Bs related from A.