<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Alexander Saint Croix&apos; Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/saintx/" />
<modified>2008-04-20T17:09:38Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/saintx/447</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2008, saintx</copyright>
<entry>
<title>OpenEJB 3.0 Final is released</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/saintx/archive/2008/04/openejb_30_fina.html" />
<modified>2008-04-20T17:09:38Z</modified>
<issued>2008-04-20T17:09:33Z</issued>
<id>tag:weblogs.java.net,2008:/blog/saintx/447.9575</id>
<created>2008-04-20T17:09:33Z</created>
<summary type="text/plain">The OpenEJB developer team has completed the official OpenEJB 3.0 final release, which is their first major release since early January 2008. Congratulations to the developers and to the Apache Software Foundation for this major milestone!</summary>
<author>
<name>saintx</name>

<email>saintx@umn.edu</email>
</author>
<dc:subject>Community: Java Enterprise</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/saintx/">
<![CDATA[<p>The OpenEJB developer team has completed the official OpenEJB 3.0 final release, which is their first major release since early January 2008. Congratulations to the developers and to the Apache Software Foundation!</p>

<p>As an enthusiast and grateful OpenEJB user, I figured in addition to cutting over my projects to use the new release, I'd post something at J.N about it in case others are interested.  Here are the truncated release notes from their user mailing list.</p>

<p>Download binaries here:</p>

<p> http://openejb.apache.org/download.html<br />
 (check http://cwiki.apache.org/OPENEJB/openejb-30.html of the above page hasn't synched yet)</p>

<p><br />
Apache OpenEJB 3.0 Release Notes</p>

<p>New Features:</p>

<p> * [OPENEJB-769] Dependency Injection of Enums<br />
 * [OPENEJB-768] Dependency Injection of Collections and Maps using Java Generics<br />
 * [OPENEJB-758] @EJB references to local interfaces in other ears<br />
 * [OPENEJB-777] Transaction Logging<br />
 * [OPENEJB-788] Host based authorization on remote client requests</p>

<p>Improvements:</p>

<p> * [OPENEJB-784] Improved support for annotation inheritance<br />
 * [OPENEJB-787] Improved client request thread pooling and backlog control<br />
 * [OPENEJB-760] Improved Circular and Lazy EJB reference resolution between ears<br />
 * [OPENEJB-764] New openejb.validation.output.level property settable to TERSE, MEDIUM, or VERBOSE<br />
 * [OPENEJB-763] Auto create non-jta-data-source as a clone of jta-data-source and vice versa<br />
 * [OPENEJB-756] Allow CMP2 ejbSelect returning void for UPDATE and DELETE queries<br />
 * [OPENEJB-759] Improved and expanded EJB reference resolution<br />
 * [OPENEJB-215] Passivation/Activation of non-Serializable Stateful SessionBeans<br />
 * [OPENEJB-770] Validation: Bean class with no Interfaces<br />
 * [OPENEJB-775] Validation: Bean-class-only annotations not used on interfaces<br />
 * [OPENEJB-773] Validation: Combined use of @Stateless @Stateful and @MessageDriven on same class<br />
 * [OPENEJB-774] Validation: Component and Business Interfaces are interface types<br />
 * [OPENEJB-771] Validation: Use of @Stateless, @Stateful or @MessageDriven on an interface or abstract class<br />
 * [OPENEJB-779] Validation: Conflicting use of @RolesAllowed, @PermitAll on a class<br />
 * [OPENEJB-780] Validation: Conflicting use of @RolesAllowed, @PermitAll, @DenyAll on a method<br />
 * [OPENEJB-781] Validation: Timeout method syntax<br />
 * [OPENEJB-770] Validation: Bean class with no Interfaces<br />
 * [OPENEJB-771] Validation: Use of @Stateless, @Stateful or @MessageDriven on an interface or abstract class<br />
 * [OPENEJB-773] Validation: Combined use of @Stateless @Stateful and @MessageDriven on same class<br />
 * [OPENEJB-774] Validation: Component and Business Interfaces are interface types<br />
 * [OPENEJB-775] Validation: Bean-class-only annotations not used on interfaces</p>

<p>Bugs:</p>

<p> * [OPENEJB-767] Paths with spaces may result in "Unable to scrape for @Stateful, @Stateless or @MessageDriven annotations"<br />
 * [OPENEJB-778] Application in apps dir are sometimes not loaded at startup<br />
 * [OPENEJB-607] Cannot access server(s): null:-1 when InitialContext.PROVIDER_URL is hostname not IP address<br />
 * [OPENEJB-766] EJBs and persistence units in a web application nested in an ear are not detected<br />
 * [OPENEJB-765] POJO webservices broken in Tomcat initialized with OpenEJBListener<br />
 * [OPENEJB-782] RollbackException swallowed in TransactionPolicy<br />
 * [OPENEJB-700] Must have java.sun.com access when online to deploy: Cannot unmarshall the ejb-jar.xml file<br />
 * [OPENEJB-761] Tomcat EAR double deployment<br />
 * [OPENEJB-750] EJB 2 Entity bean with CMP field mapped to CMR field causes ClassFormatError<br />
 * [OPENEJB-717] ServiceRef converts JAX-RPC handlers into JAX-WS handlers<br />
 * [OPENEJB-762] CMP finder with no results: NullPointerException in TransactionPolicy.logSystemException()<br />
 * [OPENEJB-754] Print out the provider in Configuring PersistenceUnit(name=testFacadePu, provider=null) log message<br />
 * [OPENEJB-757] JavaAgent upgrade/uninstall with Tomcat</p>]]>

</content>
</entry>
<entry>
<title>The tense relationship between JPA, enums and generics</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/saintx/archive/2008/04/the_tense_relat.html" />
<modified>2008-04-19T19:10:47Z</modified>
<issued>2008-04-19T19:10:43Z</issued>
<id>tag:weblogs.java.net,2008:/blog/saintx/447.9571</id>
<created>2008-04-19T19:10:43Z</created>
<summary type="text/plain">There is a triad of tradeoffs between enums, generics, and the current JPA specification that can lead to a lot of development headache.  What are some ways to negotiate these hurdles?</summary>
<author>
<name>saintx</name>

<email>saintx@umn.edu</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/saintx/">
<![CDATA[<p>In the last two months, I've come to understand in excruciating detail the various tradeoffs between using generics and enums in my JPA-ready entity library.  Most recently, I've been inspired to write down some of my notes, to save myself and others some headache in the future.</p>]]>
<![CDATA[<p>First of all, as always, a pattern is necessary to illustrate the problems I've seen.  Consider the task of persisting a unit definition.  Here are some examples of instances of a Unit object: kilogram, second, meter, candela.</p>

<p>Clearly these objects all would benefit from having a name, description and ID field.  But consider these as well: joule, watt, newton.  Now, the first three units were SI base units.  The second three can be defined <em>in terms</em> of the first three.  For example, a newton is equal to m∙kg∙s<sup>−2</sup>.  So it becomes clear that units need to be able to be defined according to an underlying terminology.</p>

<p>So, let's say we have a Term class, with a coefficient, a radix and an exponent.  The newton Unit instance would now contain a List of three Term instances.  The first term has a coefficient of 1, a radix of the "meter" instance, and an exponent of 1.  The second term is much like the first, save for the fact that its radix is equal to the "kilogram" instance of the Unit class.  The third follows a similar pattern, but in addition to referencing the "second" Unit instance, it also has an exponent of -2.</p>

<p>Now, for consistency and convenience, we'll define base units <em>in terms</em> of themselves.  So, a "meter" instance contains a list of one Term, with a coefficient of 1, a radix of the "meter" instance, and an exponent of 1.</p>

<p>Finally, we can also give the Unit class a boolean field, in order to distinguish between base units and derived units. This very basic definition of units and terms will suffice for what I'm trying to explain.</p>

<p>Now, so far, we have two entities, Unit and Term, and a very simple Many-to-Many relationship between them.  But here's where the trouble starts.</p>

<p>Part of the purpose of capturing the concept of a Unit in an object-oriented manner is so that we can use them to create constraints on logical behavior that are more rich and efficient than we'd be able to accomplish were they mere text fields.  We also want to capture, in some way, the relationships between different units.  </p>

<p>To illustrate the first point, consider that you're writing an application where you want to add together a collection of units to determine their sum total.  Now, imagine your assumption is that you're trying to get a combined measurement of mass.  If you have an object that represents "3 kilograms" and another that represents "5 kilograms" you can easily accomplish this.  But what if in addition to these, someone slipped in an object representing "4 seconds"?  What is 3kg + 5kg + 4s?</p>

<p>Now we're dealing with <em>dimensional analysis</em>.  There are rules that stipulate, you cannot add these together.  It'll break your logic.  So, what you want to do--what you <em>need</em> to do, is to somehow capture the idea that your "kilogram" units are tied to the concept of "mass", that your "second" objects are tied to the concept of "time", that your "tesla" objects are tied to the concept of "magnetic flux density", and so forth.</p>

<p>But what are these concepts "time", "mass", "magnetic flux density", "photoelastic work", "molar entropy", and so forth?  Well, it turns out there is some fog in the answer to that question.  Depending on which poorly written wikipedia article you find, these concepts are collectively called "quantities", "dimensions", "magnitudes" or even "quantitative properties of particles".  It turns out there is no highly rigorous name for them, but since Object-Oriented programming is nothing if not nominalist and aristotelian in nature, they needed to be named.  In order not to limit my future use of the above terms, I decided against adopting any of them and named these objects according to their relationship to the Unit.  Since these concepts serve to <em>limit the scope of what the unit can be used to quantify</em>, I refer to them as the <em>Quantitative Scopes</em> of a unit.  Please, if you're a physicist studying dimensional analysis, don't be upset.</p>

<p>Because, whatever these are called, we are now straying into trouble with Java.  Case in point, how does one best represent a quantitative scope?</p>

<p>Well, generics give us one <em>tantalizing</em> option.  I'd like to be able to create a <code>new Unit&lt;Mass&gt;()</code>, and keep it in a <code>Set&lt;Unit&lt;Mass&gt;&gt;</code>.  I think this would afford me with the best and easiest way to constrain the use of these units.  However, that leaves us with the difficult problem of how "Mass" is represented.</p>

<p>We have only two options here.  Class or Interface.  Class is problematic, because every instance of "Mass" would be identical to every other.  So, it makes more sense to use Interfaces.  Ah, but herein lies the rub, because our <em>original goal</em> was to make these objects persistent.  And Interfaces, bless their bytecode, certainly do <em>not</em> fit this bill.</p>

<p>So, it seems objects are the only option.  But this, once again, leaves us with the problem of instance control.  I could rattle off 126 examples of a QuantitativeScope object, each differing from the other only in name.  But if we define each as a class, then presumably we'd have 126 database tables filled with carbon copied records, which is just not going to happen.  Thus, the quandary.  Interfaces cannot be made persistent, but classes are the wrong instrument to accomplish the goal.</p>

<p>Well, <em>what about enums?</em>  It's an idea--an enum would nicely solve the persistence problem, but it doesn't save us on the application layer because <em>enum-valued objects cannot be used in generic fields</em>.  Furthermore, enum-valud objects <em>cannot be given generic fields themselves</em>.  This makes sense, given what enums are <em>for</em>, but it leads us back to the same problem.  How, given all three of these tools, are we to accomplish the goal of being able to discriminate easily between units of different quantitative scope while not abandoning the ability to persist the objects?</p>

<p>I came up with an ugly hack to solve this problem.  The good news is that it makes the best use of the available technology that I'm able to determine.  The bad news is that it's an <em>ugly hack</em> and it fills me with doubt about Java and JPA.  But I'm invested in making this work, so here goes:</p>

<p>First, I created a "Scope" enum, with 126 different values in it.  Scope.Mass, Scope.Time, etc.  Then, I made 126 corresponding interfaces, "Mass", "Time", etc., that extend a base "QuantitativeScope" interface.  Third, I made a generified "Graft" class that serves to bind one of these interfaces "Q extends QuantitativeScope" to one of these enum-valued objects.  Finally, I defined a library class containing 126 public abstract final instances of this "Graft" class, each mapped to the appropriate "Scope" enum-valued object.  With these graft instances, I was set.</p>

<p>Now, when defining a Unit, I can pass one of these "Graft" objects to the UnitFactory.  It can get both the generic type from this Graft object, and assign the Graft.getScope() enum-valued object to a "scope" field in the Unit class.  When I persist the Unit into JPA, the "scope" field, which is defined as @Enumerated(EnumType.STRING), goes into the database.  When I get a collection of Unit objects back out of the database, I can run them through a seive and inspect each of their Unit.getScope() values in a <code>switch</code> statement, then place them into appropriately generified Set objects.  This piece works sort of like a coin sorter, but when I'm done I can ask for the Set&lt;Unit&lt;Mass&gt;&gt; and know that my results are reliable.</p>

<p>The main problem with this workaround is that I had to duplicate a lot of data and encase it into interfaces, a large enum, <em>and</em> a graft object library in order to make it function.  There are other lingering problems with this approach as well, and I'm sure that I'll uncover more and more of them as I continue.</p>

<p>What this has taught me is that enums and generics are exceedingly tricky to use.  Although with generics, Types can now be used as compile-time constraints on behavior, they don't help you at runtime, and are therefore tough to work into a persistence application.  This worsens the intrinsic impedence mismatch between the application layer and the persistence layer in application design.  Further, enums in Java behave like pseudotypes, somewhere between Interfaces and Classes, but because they cannot be used as Generic Types, they even further aggravate the impedence mismatch when worked into a persistent application design.  If I could have used the enum valued objects in the generic fields, this would be a non-problem.</p>

<p>Finally, the best solution for my particular problem might have nothing to do with enums or generics after all.  What I'm trying to replicate through this design is actually <em>Invariants</em>, <em>Preconditions</em> and <em>Postconditions</em> on method behavior, class definitions, and collection compositions.  There are languages such as VDM-SL and Eiffel that wonderfully exemplify this sort of language feature, and old tools such as iContract that might make it useful in Java, but it's a shame that these useful tools are not built into the language itself.</p>]]>
</content>
</entry>
<entry>
<title>Persistence of JScience components a no-go?</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/saintx/archive/2008/02/persistence_of.html" />
<modified>2008-02-10T18:05:22Z</modified>
<issued>2008-02-10T18:05:14Z</issued>
<id>tag:weblogs.java.net,2008:/blog/saintx/447.9176</id>
<created>2008-02-10T18:05:14Z</created>
<summary type="text/plain">Beware casual use of JScience.org if your model is to become persistent.  You might be walking into a snake pit.</summary>
<author>
<name>saintx</name>

<email>saintx@umn.edu</email>
</author>
<dc:subject>Programming</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/saintx/">
<![CDATA[<p>When I first stumbled upon the JSR-275 standard units RI at JScience.org last autumn, I was very impressed with its careful design and eager to use it in my projects.  That was before I began working on JPA persistence annotations for my data model.  Now I regret using this otherwise wonderful package, for I've become entrenched in an ugly decision between shedding JScience.org dependencies entirely and reimplementing, annotating a partial branch of JScience.org for use in my project, or building some kind of bridging data class and corresponding transformer layer.</p> 

<p>Neither option is attractive.  Lesson learned.</p>]]>

</content>
</entry>
<entry>
<title>Mastering EJB transaction control with . . . Lambda?</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/saintx/archive/2008/02/lambda_function.html" />
<modified>2008-02-09T17:54:08Z</modified>
<issued>2008-02-09T17:54:01Z</issued>
<id>tag:weblogs.java.net,2008:/blog/saintx/447.9173</id>
<created>2008-02-09T17:54:01Z</created>
<summary type="text/plain">&quot;A procedure always operates in the environment in which it was created.&quot;  Check out how you can mimic the (lambda) functionality of LISP with Java using anonymous inner classes.</summary>
<author>
<name>saintx</name>

<email>saintx@umn.edu</email>
</author>
<dc:subject>Programming</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/saintx/">
<![CDATA[<p>My friend David Blevins showed me a great trick the other day.  I was writing some in-container tests for an EJB/JPA application I'm working on, and needed some power tools to better control the scope of my transactions.  After no small amount of pain, I became comfortable with the idea of increasing the <strong>similarity</strong> of the tests.  That is to say, the tests needed to more carefully reflect the actual usage scenario that end users would encounter.  Key to this was the concept of <strong>units of work</strong>.  The mechanism he showed me for acheiving this very closely mimics Lambda notation from languages like LISP.</p>]]>
<![CDATA[<p>A unit of work is, more or less, the greatest amount of "work" that can be performed in a single transaction without adversely impacting performance by tying up database connections.  If your units of work are too long, you chew up connection resources.  If they are too small, you waste resources on creating lots of new small connections.  So, the trick is to find the "sweet spot".  How much work is enough?</p>

<p>As my software engineering professor Mats Heimdahl would sagely advise, "It depends."</p>

<p>The truth is that regardless of how big or small your transactions are, it's easy to get them wrong, and you need to do them correctly each time in order to guarantee that your application and tests perform and behave in a predictable manner.  So, if you can abstract this element of your software, you are likely to be much better off.</p>

<p>To make a long story short, David showed me a pattern that I found indespensable for testing, because it mimics the lambda capabilities of languages like LISP.</p>

<p>Here's a look.</p>

<p>I have a base testing class that contains infrastructure for my tests.  It looks something like this:</p>

<pre>
package org.eremite.corm.party.testutil;

import junit.framework.TestCase;
import org.eremite.corm.Archetype;

import javax.annotation.security.RunAs;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.naming.Context;
import javax.naming.NamingException;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.Callable;

public abstract class CascadeTestBase extends TestCase {

    protected Context context = ContextFactory.reference();
    protected BeanManager mgr;

    public void setUp() throws Exception {
        super.setUp();
        mgr = (BeanManager) context.lookup(
            "BeanManagerLocal");
    }

    public void tearDown() throws Exception {
        super.tearDown();
    }

    protected static void traceln(Object... o) {
//        for(Object item : o) System.out.println(item);
    }

    protected boolean hasArchetypeWithID(Set s, long ID) {
        Iterator&lt;Archetype&gt; iter = 
            (Iterator&lt;Archetype&gt;) s.iterator();
        while (iter.hasNext()) {
            Archetype a = iter.next();
            if (a != null && a.getID() == ID) return true;
        }
        return false;
    }

    protected Archetype getArchetypeWithID(Set s, long ID) {
        Iterator&lt;Archetype&gt; iter = 
            (Iterator&lt;Archetype&gt;) s.iterator();
        while (iter.hasNext()) {
            Archetype a = iter.next();
            if (a != null && a.getID() == ID) return a;
        }
        return null;
    }

    protected void clear(String... tables) {
        for (String table : tables) mgr.clear(table);
    }

    public class Retriever&lt;A extends Archetype&gt; {
        private String table;
        private long ID;

        public Retriever(String table, long ID) {
            this.table = table;
            this.ID = ID;
        }

        public A fetch() {
            ExtendedBeanManager&lt;A&gt; mgr = null;

            try {
                mgr = 
                    (ExtendedBeanManager&lt;A&gt;) 
                        context.lookup(
                            "ExtendedBeanManagerLocal");
                            
            } catch (NamingException e) {
                e.printStackTrace();
            }

            return mgr.find(table, ID);
        }

        public A fetchWith(String column) {

            ExtendedBeanManager&lt;A&gt; mgr = null;

            try {
                mgr = (ExtendedBeanManager&lt;A&gt;) 
                    context.lookup(
                        "ExtendedBeanManagerLocal");
            } catch (NamingException e) {
                e.printStackTrace();
            }

            return mgr.findAll(table, column, ID).
                iterator().next();
        }
    }

    // - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //  Courtesy of David Blevins from the OpenEJB project
    //  These beans will get picked up if you have an empty
    //  src/test/resources/META-INF/ejb-jar.xml
    //  file which simply contains the text "&lt;ejb-jar/&gt;"
    // - - - - - - - - - - - - - - - - - - - - - - - - - - -

    public static interface Caller {
        public &lt;V&gt; V call(Callable&lt;V&gt; callable) 
            throws Exception;
    }

    @Stateless
    @TransactionAttribute(
        TransactionAttributeType.REQUIRES_NEW)
    public static class TransactionBean implements Caller {
        public &lt;V&gt; V call(Callable&lt;V&gt; callable) 
            throws Exception {
            return callable.call();
        }
    }

    @Stateless
    @RunAs("manager")
    public static class SecureBean implements Caller {
        public &lt;V&gt; V call(Callable&lt;V&gt; callable) 
            throws Exception {
            return callable.call();
        }
    }

    @Stateless
    @RunAs("manager")
    @TransactionAttribute(
        TransactionAttributeType.REQUIRES_NEW)
    public static class SecureTransactedBean 
        implements Caller {
        public &lt;V&gt; V call(Callable&lt;V&gt; callable) 
            throws Exception {
            return callable.call();
        }
    }

    public void testTransaction() throws Exception {
        Caller transactional = (Caller) 
            context.lookup("TransactionBeanLocal");
        for(Callable item : getCalls()) {
            transactional.call(item);
        }
    }

    // Test cases are required to implement this method.
    public abstract Callable[] getCalls();
}
</pre>

<p>Note, most importantly, the enterprise beans at the bottom.  One of them, "TransactionBean", is the one I use in my test classes to actually perform my transactions.</p>

<p>Now, for the sake of brevity, I'm going to refrain from describing the data model that I'm testing.  For now assume it's a commercial object-relational model that closely obeys the principle of least astonishment, and that every entity extends a managed superclass "Archetype". Also, without going into the implementation details, here is the interface definition for the BeanManager class used in the class above:</p>

<pre>
package org.eremite.corm.party.testutil;

import org.eremite.corm.Archetype;

import javax.ejb.Local;
import java.util.List;

@Local
public interface BeanManager&lt;A extends Archetype&gt; {

    public long persist(Archetype a);
    public void merge(Archetype a);
    public void remove(Archetype a);
    public long sizeOf(String table);
    public void clear(String table);
    public void flush();

    public List&lt;A&gt; query(String s);
    public A find(String table, long ID);
    public List&lt;A&gt; findAll(String table);
    public List&lt;A&gt; findAll(String table, String field);
    public List&lt;A&gt; findAll(
        String table, String field, long ID);
}
</pre>

<p>Given the two base utilities above, I can now do the following in my individual test classes in order to ensure the cascading behavior for collection-valued and field-valued entity references from any given entity:</p>

<pre>
package org.eremite.corm.party;

import org.eremite.corm.Archetype;
import org.eremite.corm.party.address.Address;
import org.eremite.corm.party.address.AssociatedAddress;
import org.eremite.corm.party.testutil.CascadeTestBase;

import java.util.Set;
import java.util.concurrent.Callable;

public class AddressCascadeTest extends CascadeTestBase {

    private Address address1, address2, address3;
    private Party party1;
    private AssociatedAddress aa1;
    private Archetype party2, party3, aa2, aa3;
    private long ID, partyID, aaID;
    Retriever&lt;Address&gt; bean;

    /**
     * Initialize objects and persist.
     * @return Callable block
     */
    private Callable unitOfWork_01() {
        return new Callable() {
            public Object call() {
                // initialize objects
                address1 = new Address();
                party1 = new Party();
                aa1 = new AssociatedAddress(
                    party1, address1);

                // ensure that the objects are wired up
                assertTrue(
                    address1.getParties().contains(aa1));
                    
                assertTrue(
                    party1.getAddresses().contains(aa1));
                    
                assertEquals(party1, aa1.getParty());
                assertEquals(address1, aa1.getAddress());

                mgr.persist(address1);
                mgr.flush();

                // assign the IDs
                ID = address1.getID();
                partyID = party1.getID();
                aaID = aa1.getID();

                // ensure the IDs are nonzero
                assertNotSame(0, ID);
                assertNotSame(0, partyID);
                assertNotSame(0, aaID);

                // Done.
                return null;
            }
        };
    }

    /**
     * Verify cascading persist and make updates.
     * @return Callable block
     */
    private Callable unitOfWork_02() {
        return new Callable() {
            public Object call() {
                // Verify base conditions
                assertEquals(1, mgr.sizeOf("Address"));
                assertEquals(1, mgr.sizeOf(
                    "AssociatedAddress"));
                    
                assertEquals(1, mgr.sizeOf("Party"));

                // Get new copy of stem object from DB
                bean = new Retriever&lt;Address&gt;(
                    "Address", ID);
                    
                address2 = bean.fetchWith("parties");
                assertNotNull(address2);

                // Get object from collection-valued ref
                Set&lt;AssociatedAddress&gt; assocs = 
                    address2.getParties();
                    
                assertNotNull(assocs);
                assertEquals(1, assocs.size());
                assertTrue(hasArchetypeWithID(assocs, aaID));
                aa2 = getArchetypeWithID(assocs, aaID);
                assertNotNull(aa2);

                // Make some changes.
                address2.setName("address");
                aa2.setName("associated address");

                // Done.
                return null;
            }
        };
    }

    /**
     * Verify cascading updates and delete the stem object.
     * Verify the scope of the cascading delete.
     * Remove objects left over from the cascading delete.
     * Verify the objects were removed.
     * @return Callable block
     */
    private Callable unitOfWork_03() {
        return new Callable() {
            public Object call() {
                // Verify base conditions
                assertEquals(1, mgr.sizeOf("Address"));
                assertEquals(1, mgr.sizeOf(
                    "AssociatedAddress"));
                    
                assertEquals(1, mgr.sizeOf("Party"));

                // Get new copy of stem object from db
                address3 = bean.fetchWith("parties");
                assertNotNull(address3);

                // Get object from collection-valued ref
                Set&lt;AssociatedAddress&gt; assocs = 
                   address3.getParties();
                assertNotNull(assocs);
                assertEquals(1, assocs.size());
                assertTrue(hasArchetypeWithID(assocs, aaID));
                aa3 = getArchetypeWithID(assocs, aaID);
                assertNotNull(aa3);

                // Verify earlier changes.
                assertEquals(
                    address2.getName(), 
                    address3.getName());
                    
                assertEquals(
                    aa2.getName(), 
                    aa3.getName());

                // Remove stem object
                mgr.remove(address3);
                mgr.flush();

                // Verify scope of cascading deletion
                assertEquals(0, mgr.sizeOf("Address"));
                assertEquals(0, mgr.sizeOf(
                    "AssociatedAddress"));
                    
                assertEquals(1, mgr.sizeOf("Party"));

                // Clean up leftovers
                mgr.remove(new Retriever&lt;Party&gt;(
                    "Party", 
                    partyID).fetch());
                    
                mgr.flush();

                // Verify cleanup
                assertEquals(0, mgr.sizeOf("Party"));

                // Done.
                return null;
            }
        };
    }

    /**
     * Retrieve units of work for this test case
     * @return Callable[] units of work
     */
    public Callable[] getCalls() {
        return new Callable[]{
                unitOfWork_01(),
                unitOfWork_02(),
                unitOfWork_03()
        };
    }
}
</pre>

<p>Now, the three objects that encapsulate the units of work in the test case above obey the originally stated principle that "procedures operate in the environment in which they were created."  We are sending each of the code blocks wrapped up in these anonymous inner classes to be executed by another object.</p>

<p>But, more importantly, we're <em>sending their environments with them</em>.  This is the environment we assembled in this particular test case, which contains the object IDs, and the memory references.</p>

<p>By making <code>CascadeTestBase</code> class abstract, I force all of the subclasses to implement the <code>getCalls()</code> method, which is called by the lone test case in <code>CascadeTestBase</code>.</p>

<p>By using anonymous inner classes, I am able to generate unnamed implementations of the <code>Callable</code> interface and pass their contents <em>and their enclosing environments</em> around in a manner functionally identical to <code>lambda</code> calls in LISP!</p>

<p>Next time I'll show you how I implemented ALL of the CRUD tests for my first persistence module using this pattern in fewer than 200 lines of code.</p>]]>
</content>
</entry>

</feed>