You are here: Basics Operations & Concepts > Update Concept > Update Depth In Action

Update Depth In Action

Let's see db4o's update depth in action. We store a few cars with their pilots in the database. Then we update a car and its driver and store the car. The we reopen the database and check if everything was updated. To our surprise the car-name was updated, but the driver isn't. This is the direct result of db4o's update depth policy. It only updates object to a certain update-depth.

using (IObjectContainer container = Db4oEmbedded.OpenFile(DatabaseFile))
{
    Car car = QueryForCar(container);
    car.CarName = "New Mercedes";
    car.Driver.Name = "New Driver Name";

    // With the default-update depth of one, only the changes
    // on the car-object are stored, but not the changes on
    // the person
    container.Store(car);
}
using (IObjectContainer container = Db4oEmbedded.OpenFile(DatabaseFile))
{
    Car car = QueryForCar(container);
    Console.WriteLine("Car-Name:" + car.CarName);
    Console.WriteLine("Driver-Name:" + car.Driver.Name);
}
UpdateDepthPitfall.cs: Update depth limits what is store when updating objects
Using container As IObjectContainer = Db4oEmbedded.OpenFile(DatabaseFile)
    Dim car As Car = QueryForCar(container)
    car.CarName = "New Mercedes"
    car.Driver.Name = "New Driver Name"

    ' With the default-update depth of one, only the changes
    ' on the car-object are stored, but not the changes on
    ' the person
    container.Store(car)
End Using
Using container As IObjectContainer = Db4oEmbedded.OpenFile(DatabaseFile)
    Dim car As Car = QueryForCar(container)
    Console.WriteLine("Car-Name:" & car.CarName)
    Console.WriteLine("Driver-Name:" & car.Driver.Name)
End Using
UpdateDepthPitfall.vb: Update depth limits what is store when updating objects

Explicitly Store The Driver

One solution to this issue is to store updated object explicitly, except value objects. So in our case we would store the car and the pilot. This works fine for simple models. However as the model gets more complex this is probably not a feasible solution.

Car car = QueryForCar(container);
car.CarName = "New Mercedes";
car.Driver.Name = "New Driver Name";

// Explicitly store the driver to ensure that those changes are also in the database
container.Store(car);
container.Store(car.Driver);
UpdateDepthPitfall.cs: Explicitly store changes on the driver
Dim car As Car = QueryForCar(container)
car.CarName = "New Mercedes"
car.Driver.Name = "New Driver Name"

' Explicitly store the driver to ensure that those changes are also in the database
container.Store(car)
UpdateDepthPitfall.vb: Explicitly store changes on the driver

There also a variation of this. You can use the store method of the extended container and explicitly state the update depth for the store operation.

Car car = QueryForCar(container);
car.CarName = "New Mercedes";
car.Driver.Name = "New Driver Name";

// Explicitly state the update depth
container.Ext().Store(car, 2);
UpdateDepthPitfall.cs: Explicitly use the update depth
Dim car As Car = QueryForCar(container)
car.CarName = "New Mercedes"
car.Driver.Name = "New Driver Name"

' Explicitly state the update depth
UpdateDepthPitfall.vb: Explicitly use the update depth

Configure Update Depth

As alternative you can configure the update depth. You can increase it globally or for certain classes. It's also possible to enable cascading updates for certain classes or fields.

Transparent Persistence

You can get rid of all the update depth troubles by using transparent persistence. In this mode db4o tracks all changes and stores them. See "Transparent Persistence"