.netdb4oorphaned-objects

Prevent orphaned objects in DB4O when updating fields


I want to store Person objects in DB4O. The Person Location field can be changed over time. So I retrieve a person from the DB and call a method to set the location field to a new Location object. (I want the Location objects to be immutable i.e. DDD Value Objects).

This works, however the previously assigned Location objects remain the database. How can I configure DB4O to remove these orphaned Location objects? Or do I need some custom process to garbage collect?

Simplified classes for this example:

class Person {
    Location location;
    public void Move(Location newLocation) { 
        location = newLocation;
    }
}

class Location {
    public Location(string city) { 
        this.City = city;
        //etc
    }
    public readonly string City;
    /// more fields...
}

EDIT: Some more information - Person is meant to be an DDD aggregate root. So there are no external references to a person's internal state. If Person updates its location, then the old location should cease to exist.


Solution

  • I think there's no perfect solution available. But with some work you can nearly achieve this behavior. A similar topic is already discussed here.

    The first step would be to activate cascade-deletion on the location-field. So when a Person is deleted the location is also deleted.

    configuration.common().objectClass(Person.class).objectField("location").cascadeOnDelete(true);

    Now we need to handle the changing location case. The idea is this:

    1. Register on the activate-event. There you 'remember' which object was embedded
    2. Register on the update-event. There you check if it's still the same embedded object. If not, you delete the old on.
    3. Very important: Never ever 'share' the embedded object, otherwise it will be deleted for everyone. A simple solution is to create a copy of the Location-object whenever it's assigned.

    There is Java-Demo which implements this behavior.

    Well, this is only the concept, it's a long way to an acceptable solution:

    1. Utilize Attributes or other configuration to specify which objects are such
    2. Build a robust implementation of the event-handlers etc.
    3. A solid solution to ensure that a 'shared' location is not deleted