JPOX
JPOX
 Project  |  Ver 1.1  |  Ver 1.2  |  JDO  |  JPA  |  Guides  |  Tools
1.1 | Preparation | O/R Mapping | Runtime | Extensions | Developer
O/R Mapping
Relationships
Dependent Fields

When defining your objects to be persisted and the relationships between them, it is often required to define dependencies between these related objects. What should happen to a related object when an object is deleted ? Can the related object exist in its own right beyond the lifecycle of the other object, or should it be deleted along with the other object ? This behaviour can be defined with JDO 2 and with JPOX 1.1. Lets take an example

public class Owner
{
    private DrivingLicense license;
    private Collection cars;
    
    ...
}

public class DrivingLicense
{
    private String serialNumber;
    
    ...
}

public class Car
{
    private String registrationNumber;
    private Owner owner;
    
    ...
}

So we have an Owner of a collection of vintage Car's, and the Owner has a DrivingLicense. We want to define lifecycle dependencies to match the relationships that we have between these objects. Firstly lets look at the basic Meta-Data for the objects.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jdo SYSTEM "file:/javax/jdo/jdo.dtd">
<jdo>
    <package name="org.jpox.samples.cars">
        <class name="Owner">
            <field name="license" persistence-modifier="persistent"/>
            <field name="cars">
                <collection element-type="org.jpox.samples.cars.Car" mapped-by="owner"/>
            </field>
        </class>
        
        <class name="DrivingLicense">
        	<field name="serialNumber"/>
        </class>
        
        <class name="Car">
            <field name="registrationNumber"/>
            <field name="owner" persistence-modifier="persistent"/>
        </class>
    </package>
</jdo>

So we have an inverse 1-N relationship (no join table) between our Owner and his precious Car's, and a 1-1 relationship between the Owner and his DrivingLicense, because without his license he wouldn't be able to drive the cars :-0. What will happen to the license and the cars when the owner dies ? Well in this particular case we want to define that the when the owner is deleted, then his license will also be deleted (since it is for him only), but that his cars will continue to exist, because his daughter will inherit them. To do this we change the Meta-Data to be

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jdo SYSTEM "file:/javax/jdo/jdo.dtd">
<jdo>
    <package name="org.jpox.samples.cars">
        <class name="Owner">
            <field name="license" persistence-modifier="persistent" dependent="true"/>
            <field name="cars">
                <collection element-type="org.jpox.samples.cars.Car" mapped-by="owner" dependent-element="false"/>
            </field>
        </class>
        
        <class name="DrivingLicense">
        	<field name="serialNumber"/>
        </class>
        
        <class name="Car">
            <field name="registrationNumber"/>
            <field name="owner" persistence-modifier="persistent" dependent="false"/>
        </class>
    </package>
</jdo>

So it was as simple as just adding dependent and dependent-element attributes to our related fields. Notice that we also added one to the other end of the Owner-Car relationship, so that when a Car comes to the end of its life, the Owner will not die with it. It may be the case that the owner dies driving the car and they both die at the same time, but their deaths are independent!!

Dependent Fields is utilised in the following situations

  • An object is deleted (using deletePersistent()) and that object has relations to other objects. If the other objects (either 1-1, 1-N, or M-N) are dependent then they are also deleted.
  • An object has a 1-1 relation with another object, but the other object relation is nulled out. If the other object is dependent then it is deleted when the relation is nulled.
  • An object has a 1-N collection relation with other objects and the element is removed from the collection. If the element is dependent then it will be deleted when removed from the collection. The same happens when the collections is cleared.
  • An object has a 1-N map relation with other objects and the key is removed from the map. If the key or value are dependent and they are not present in the map more than once they will be deleted when they are removed. The same happens when the map is cleared.
Using Foreign Keys for deletion control

With JDO2 you can use "dependent-field" as shown above. As an alternative you can use the datastore-defined foreign keys and let the datastore built-in "referential integrity" look after such deletions. JPOX provides a PMF property org.jpox.deletionPolicy allowing enabling of this mode of operation.

The default setting of org.jpox.deletionPolicy is "JDO2" which performs deletion of related objects as follows

  1. If dependent-field is true then use that to define the related objects to be deleted.
  2. Else, if the column of the foreign-key field is NULLable then NULL it and leave the related object alone
  3. Else deleted the related object (and throw exceptions if this fails for whatever datastore-related reason)

The other setting of org.jpox.deletionPolicy is "JPOX" which performs deletion of related objects as follows

  1. If dependent-field is true then use that to define the related objects to be deleted.
  2. If a foreign-key is specified (in MetaData) for the relation field then leave any deletion to the datastore to perform (or throw exceptions as necessary)
  3. Else, if the column of the foreign-key field is NULLable then NULL it and leave the related object alone
  4. Else deleted the related object (and throw exceptions if this fails for whatever datastore-related reason)

So, as you can see, with the second option you have the ability to utilise datastore "referential integrity" checking using your MetaData-specified <foreign-key> elements.