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); }
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
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);
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)
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);
Dim car As Car = QueryForCar(container) car.CarName = "New Mercedes" car.Driver.Name = "New Driver Name" ' Explicitly state the 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.
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"