Deleting Structured Objects

As we have already seen, we call delete() on objects to get rid of them.

StructuredExample.java: deleteFlat
01public static void deleteFlat(ObjectContainer db) { 02 ObjectSet result=db.query(new Predicate<Car>() { 03 public boolean match(Car car){ 04 return car.getModel().equals("Ferrari"); 05 } 06 }); 07 Car found=(Car)result.next(); 08 db.delete(found); 09 result=db.get(new Car(null)); 10 listResult(result); 11 }

Fine, the car is gone. What about the pilots?

StructuredExample.java: retrieveAllPilotsQBE
1public static void retrieveAllPilotsQBE(ObjectContainer db) { 2 Pilot proto=new Pilot(null,0); 3 ObjectSet result=db.get(proto); 4 listResult(result); 5 }

Ok, this is no real surprise - we don't expect a pilot to vanish when his car is disposed of in real life, too. But what if we want an object's children to be thrown away on deletion, too?

Recursive Deletion 

The problem of recursive deletion (and its solution, too) is quite similar to the update problem. Let's configure db4o to delete a car's pilot, too, when the car is deleted.

StructuredExample.java: deleteDeepPart1
1public static void deleteDeepPart1() { 2 Db4o.configure().objectClass("com.db4o.f1.chapter2.Car") 3 .cascadeOnDelete(true); 4 }

StructuredExample.java: deleteDeepPart2
01public static void deleteDeepPart2(ObjectContainer db) { 02 ObjectSet result=db.query(new Predicate<Car>() { 03 public boolean match(Car car){ 04 return car.getModel().equals("BMW"); 05 } 06 }); 07 Car found=(Car)result.next(); 08 db.delete(found); 09 result=db.query(new Predicate<Car>() { 10 public boolean match(Car car){ 11 return true; 12 } 13 }); 14 listResult(result); 15 }

Again: Note that all configuration must take place before the ObjectContainer is opened.

Another way to organize cascaded deletion is using callbacks. The callbacks allow you to specify explicitly, which objects are to be deleted.

Recursive Deletion Revisited

But wait - what happens if the children of a removed object are still referenced by other objects?

StructuredExample.java: deleteDeepRevisited
01public static void deleteDeepRevisited(ObjectContainer db) { 02 ObjectSet result=db.query(new Predicate<Pilot>() { 03 public boolean match(Pilot pilot){ 04 return pilot.getName().equals("Michael Schumacher"); 05 } 06 }); 07 Pilot pilot=(Pilot)result.next(); 08 Car car1=new Car("Ferrari"); 09 Car car2=new Car("BMW"); 10 car1.setPilot(pilot); 11 car2.setPilot(pilot); 12 db.set(car1); 13 db.set(car2); 14 db.delete(car2); 15 result=db.query(new Predicate<Car>() { 16 public boolean match(Car car){ 17 return true; 18 } 19 }); 20 listResult(result); 21 }

StructuredExample.java: retrieveAllPilots
1public static void retrieveAllPilots(ObjectContainer db) { 2 ObjectSet result=db.get(Pilot.class); 3 listResult(result); 4 }

Currently db4o does not check whether objects to be deleted are referenced anywhere else, so please be very careful when using this feature.However it is fairly easy to implement referential checking on deletion using ObjectCanDelete callback. See Callbacks chapter for more information.