Updating Structured Objects

To update structured objects in db4o, you simply call set() on them again.

StructuredExample.java: updateCar
01private static void updateCar(ObjectContainer container) { 02 ObjectSet result = container.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 found.setPilot(new Pilot("Somebody else", 0)); 09 container.set(found); 10 result = container.query(new Predicate<Car>() { 11 public boolean match(Car car) { 12 return car.getModel().equals("Ferrari"); 13 } 14 }); 15 listResult(result); 16 }

Let's modify the pilot, too.

StructuredExample.java: updatePilotSingleSession
01private static void updatePilotSingleSession( 02 ObjectContainer container) { 03 ObjectSet result = container.query(new Predicate<Car>() { 04 public boolean match(Car car) { 05 return car.getModel().equals("Ferrari"); 06 } 07 }); 08 Car found = (Car) result.next(); 09 found.getPilot().addPoints(1); 10 container.set(found); 11 result = container.query(new Predicate<Car>() { 12 public boolean match(Car car) { 13 return car.getModel().equals("Ferrari"); 14 } 15 }); 16 listResult(result); 17 }

Nice and easy, isn't it? But there is something that is not obvious in this example. Let's see what happens if we split this task in two separate db4o sessions: In the first we modify our pilot and update his car:

StructuredExample.java: updatePilotSeparateSessionsPart1
01private static void updatePilotSeparateSessionsPart1( 02 ObjectContainer container) { 03 ObjectSet result = container.query(new Predicate<Car>() { 04 public boolean match(Car car) { 05 return car.getModel().equals("Ferrari"); 06 } 07 }); 08 Car found = (Car) result.next(); 09 found.getPilot().addPoints(1); 10 container.set(found); 11 }

And in the second, we'll double-check our modification:

StructuredExample.java: updatePilotSeparateSessionsPart2
1private static void updatePilotSeparateSessionsPart2( 2 ObjectContainer container) { 3 ObjectSet result = container.query(new Predicate<Car>() { 4 public boolean match(Car car) { 5 return car.getModel().equals("Ferrari"); 6 } 7 }); 8 listResult(result); 9 }

[/filter] 

 

StructuredExample.java: updatePilotSeparateSessionsImprovedPart2
01private static void updatePilotSeparateSessionsImprovedPart2( 02 ObjectContainer container) { 03 ObjectSet result = container.query(new Predicate<Car>() { 04 public boolean match(Car car) { 05 return car.getModel().equals("Ferrari"); 06 } 07 }); 08 Car found = (Car) result.next(); 09 found.getPilot().addPoints(1); 10 container.set(found); 11 }

[/filter] 

[filter=vb]

StructuredExample.vb: UpdatePilotSeparateSessionsImprovedPart3
1Private Shared Sub UpdatePilotSeparateSessionsImprovedPart3(ByVal db As IObjectContainer) 2 Dim result As IObjectSet = db.Get(New Car("Ferrari")) 3 ListResult(result) 4 End Sub

You can also achieve expected results using:

  1. ExtObjectContainer#set(object, depth) to update exact amount of referenced fields
  2. Use configuration.objectClass(clazz).updateDepth(depth) setting to define sufficient update depth for a specific object
  3. Use global setting for all the persisted objects:

Java:

configuration.updateDepth(depth);

However global updateDepth is not flexible enough for real-world objects having different depth of reference structures.

ATTENTION: Setting global update depth to the maximum value will result in serious performance penalty. Please, use this setting ONLY for debug purposes.

Note that container configuration must be set before the container is opened and/or passed to the openFile/openClient/openServer method.