Jaffa Logo
 
SourceForge.net
Home Contact Us FAQs Site Map
Source Forge: Homepage Bugs @ Sourceforge Mailing Lists @ Sourceforge Task Manager @ Sourceforge CVS @ Sourceforge
Jaffa Site
Jaffa Runtime
Jaffa RAD
Sub-Projects
How To / Managing Relationships

The hardest thing with persistent objects is managing the relationships between them. This covers the basic approaches for this, regardless of whether the persistence engine natively supports them

Contents

  1. Native Support
  2. Non-Encapsulated
  3. Encapsulated

Native Support

  • The persistence engine transparently loads the related objects (as specified in the mapping files), when an object is loaded from the database. If lazy loading is specified, then the related objects will utilize virtual proxies, and will be loaded on demand. Additions, updations and deletions of related objects will also be natively supported.

  • This kind of capability requires a well-designed normalized database, which uses object ids as primary keys. Refer to the Scott Ambler paper (http://www.ambysoft.com/persistenceLayer.pdf) for more information.

  • Castor is an example of such a persistence engine. But currently, it is not supported.

  • Example - Assume that the Part table has an aggregate relationship with the Item table (this will have to specified in the mapping file, in ways as yet undefined). The Part domain object will contain a Collection of related Item domain objects. This Collection will be filled with appropriate objects by the persistence engine, transparently, whenever a Part object is loaded. The Part object will support the following methods, in addition to the regular get/set/update/validate methods for the various fields.
    Example Domain Object Code
    public Collection getItemCol() {
       return m_itemCol;
    }
    public void addItem(Item item) {
       m_itemCol.add(item);
    }
    public void deleteItem(Item item) {
       m_itemCol.remove(item);
    }
    

  • To print out the Serial for each Item for a Part, the client class will have the following code:
    Example Query
    UOW uow = new UOW();
    Criteria c = new Criteria();
    c.setTable(PartMeta.getName());
    c.addCriteria(PartMeta.PART_NO, "P1");
    Iterator parts = uow.query( c ).iterator();
    if (parts.hasNext()) {
        Part part = (Part) itr.next();
        for (Iterator items = part.getItemCol().iterator; items.hasNext(); )
            System.out.println( ((Item) items.next()).getSerial() );
    }
    

Note: The current JDBC Engine does not support native relationship management, however the original prototype persistence engine based on Castor did, as this was a feature of Castor.

Non-Encapsulated

  • This is the case when the persistence engine provides no support for managing relationships. The client classes will have to manually add/update/delete related objects for a domain object.

  • To print out the Serial for each Item for a Part, the client class will have the following code-
    Example Query
    UOW uow = new UOW();
    Criteria c = new Criteria();
    c.setTable(PartMeta.getName());
    c.addCriteria(PartMeta.PART_NO, "P1");
    Iterator parts = uow.query( c ).iterator();
    if (parts.hasNext()) {
        Part part = (Part) itr.next();
        Criteria  c1 = new Criteria();
        c1.setTable(ItemMeta.getName());
        c1.addCriteria(ItemMeta.PART_NO, part.getPartNo());
        Iterator items = uow.query(c1).iterator();
        while (items.hasNext())
            System.out.println( ((Item) items.next()).getSerial() );
    }
    

Note: This may be the best solution if you are 'persistence enabling' and existing legacy data model, where the relationships are very 'ad-hoc' and the model is not well normalized.

Note: This is the strategy that we have currently implemented in the V1.0 Domain Object Pattern. See the Domain Object How To for more details.

Encapsulated

  • This is the cross of the above 2 methods. The persistence engine still provides no support for managing relationships. However, the relationship can be built into the domain classes, manually.

  • Continuing with the above example, the Part domain object will contain a Collection of related Item domain objects. However, this Collection will have to be filled manually with appropriate objects. The Part object will support the following methods, in addition to the regular get/set/update/validate methods for the various fields.
    Example Domain Object Code
    public Collection getItemCol() {
        if (m_itemCol == null) {
            Criteria c = new Criteria();
            c.setTable(ItemMeta.getName());
            c.addCriteria(ItemMeta.PART_NO, this.getPartNo());
            m_itemCol = this.getUOW().query(c);
        }
        return m_itemCol;
    }
    public void addItem(Item item) {
        if (m_itemCol == null)
            m_itemCol = new ArrayList();
        m_itemCol.add(item);
    }
    public void deleteItem(Item item) {
        if (m_itemCol == null || ! m_itemCol .contains(item))
            throw new DeleteFailedException();
        m_itemCol.remove(item);
    }
    

  • To print out the Serial for each Item for a Part, the client class will have the following code:
    Example Query
    UOW uow = new UOW();
    Criteria c = new Criteria();
    c.setTable(PartMeta.getName());
    c.addCriteria(PartMeta.PART_NO, "P1");
    Iterator parts = uow.query( c ).iterator();
    if (parts.hasNext()) {
        Part part = (Part) itr.next();
        for (Iterator items = part.getItemCol().iterator; items.hasNext(); )
            System.out.println( ((Item) items.next()).getSerial() );
    }
    

Note: If you plan to migrate your code between a non-native and native persistence engine, then it is recommended that you use some kind of pattern and code generation engine, such that you can initially generate all your domain objects in an encapsulated fashion for the non-native engine, and at a later date re-generate them will a modified pattern that remove the encapsulated code so they will run on a native engine.


File: relationships.html, Last Modified: Tue Jul 15 2003 at 4:02:03pm. This site has been built using PPWIZARD