<?xml version="1.0" encoding="UTF-8"?>
<!--
  Copyright 2002-2004 The Apache Software Foundation or its licensors,
  as applicable.
  
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  
  http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!DOCTYPE document PUBLIC "-//WAMBLEE.ORG//ENTITIES Include Extension for Xdoc V1//EN"
"includeExtension-v1.dtd">
<document> 
  <header> 
    <title>Persistence Design</title> 
  </header> 
  <body> 
    <p>This document explains the requirements and the design of support utilities for persistence.</p>
    
    <section>
      <title>Introduction</title>
      
      <p>
        Even though Hibernate when used with Spring is a complete persistence framework, we need 
        some utilities and support classes to make Hibernate easier to use. 
      </p>
    </section>
    <section id="requirements">
      <title>Requirements</title>
      
        <ol>
          <li>The persistence framework shall make it easy to implement new persistent classes 
            for Hibernate with a primary key and version. </li>
        </ol>
        
      <p>
        The package can be extended inthe future with for instance: 
      </p>
      <ul>
        <li>Useful generic persistent classes such as key-value pairs, binary arrays, and persisting
            documents as XML.</li>
      </ul>
    </section>
    
    <section id="design">
      <title>Design</title>
      <p>
        The persistence framework provides the following: 
      </p>
      <ul>
        <li>A interface and abstract class for making it easy to implement persistent objects. </li>
        <li>A base class to for implementation of Hibernate DAOs.</li>
      </ul>
    </section>
    
    <section id="structure">
      <title>Structure</title>
      
      <section>
        <title>Package Overview</title>
        
        <p>
          Persistence support is provided in two packages: 
        </p>
        <figure src="../umlpictures/class-diagram-org.wamblee.persistence.packages.jpg" 
	        alt="Package overview. " />
        <p>
          Package <code>org.wamblee.persistence</code> provides interface and utility classes for
          persistence. 
        </p>
      </section>
      
      <section>
        <title>Support for persistent objects</title>
        
        <p>
          The <code>Persistent</code> interface is the interface that every persistent object must
          implement. It provides methods for getting and setting primary key and version. These
          methods should only be used by DAO implementations and never (!) by application code.
          Specifically, <code>equals()</code> and <code>hashCode()</code> should also not use these
          methods. 
        </p>
        <figure src="../umlpictures/class-diagram-org.wamblee.persistence.persistent.jpg" 
	        alt="The Persistent interface." />
       
      </section>
      
      <section>
        <title>Support for DAOs</title>
        
        <p>
          The <code>HibernateSupport</code> class extends the Spring
          <code>HibernateDAOSupport</code> class with useful methods for DAOs. 
          The following methods are provided: 
        </p>
        <ul>
          <li><strong>merge()</strong>: This extends the standard Hibernate <code>merge()</code>
            operation by also setting the primary keys and versions of the object passed into the 
            merge operation. Standard Hibernate does not do this. Care should be taken with this 
            operation since it will lazy load all associations of the object passed to the merge 
            operation if <code>merge</code> was specified for the cascade attribute in the
            Hibernate mapping file</li>
        </ul>
        <figure src="../umlpictures/class-diagram-org.wamblee.persistence.hibernate.support.jpg"
          alt="Hibernate DAO support." />
        
      </section>
      
      
    </section>
    
    <section id="dynamics">
      <title>Dynamics</title>
      
      <p>Since the current design is trivial, no sequence diagrams are provided. </p>
      
    </section>
    
    <section>
      <title>Design Rules</title>
      
      <p>
        To use persistence support effectively, the following rules should be followed:
      </p>
      <ul>
        <li>Every persistent object should implement the <code>Persistent</code> interface</li>
        <li>Application functionality should not(!) depend on the primary key or version of the
          object.</li>
        <li>The <code>merge()</code> method of <code>HibernateSupport</code> should be used with
          caution as it will lazy load all assocations mapped with <code>cascade="merge"</code>.</li>
        <li>A data access object should never allow low-level database exceptions to pass through,
          unless the occurence of such an exception would mean that a problem in the implementation
          exists.</li>
        <li>It is recommended to implement data access in such a way that it does not depend on
          catching and interpreting database exceptions. Doing this would tie the DAO implementation
          to a database in general and to certain database features in particular. Specifically,
          foreign key constraints and primary keys are nice mechanism if the database has them, but
          these should only be used to prevent data corruption and guard against programming errors.
          Application functionality should not depend on the support of these features in the
          persistence layer. </li>
      </ul>
    </section>
    
  </body>
</document>
