Skip Headers

Oracle TopLink Developer's Guide 10g Release 3 (10.1.3) B13593-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# Controlling the Order of Delete Operations

"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:

- Using the Unit of Work setShouldPerformDeletesFirst Method

- Using the Descriptor addConstraintDependencies Method

## Using the Unit of Work setShouldPerformDeletesFirst Method

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.

## Using the Descriptor addConstraintDependencies Method

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:

1. Using deleteAllObjects Without addConstraintDependencies

2. Using deleteAllObjects with addConstraintDependencies

## Using deleteAllObjects Without addConstraintDependencies

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)

## Using deleteAllObjects with addConstraintDependencies

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.