<?xml version='1.0' encoding='utf-8' ?>
<!--  If you are running a bot please visit this policy page outlining rules you must respect. http://www.livejournal.com/bots/  -->
<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:media='http://search.yahoo.com/mrss/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>Jesse Sweetland&apos;s Programming Blog</title>
  <link>http://jsweetland.livejournal.com/</link>
  <description>Jesse Sweetland&apos;s Programming Blog - LiveJournal.com</description>
  <lastBuildDate>Sat, 13 Jan 2007 19:03:10 GMT</lastBuildDate>
  <generator>LiveJournal / LiveJournal.com</generator>
  <lj:journal>jsweetland</lj:journal>
  <lj:journalid>8191410</lj:journalid>
  <lj:journaltype>personal</lj:journaltype>
  <atom10:link rel='hub' href='http://pubsubhubbub.appspot.com/' />
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/3229.html</guid>
  <pubDate>Sat, 13 Jan 2007 19:03:10 GMT</pubDate>
  <title>JSF Session Timeouts</title>
  <link>http://jsweetland.livejournal.com/3229.html</link>
  <description>&lt;p&gt;If the application handles its own authentication, one can detect session timeouts by initializing a &quot;User&quot; object or token in the session immediately after authenticating and checking to see whether it is null using a filter.  (There are some problems with using a filter, namely that you must exclude the login page request URI from the null user check to avoid endless dispatch loops.)  In JSF this would mean storing the &quot;User&quot; object/token in a property of a session-scoped managed bean.  (If the &quot;User&quot; object is itself a session-scoped managed bean, then JSF will automatically initialize it upon request, so it will never be null.  One can still check the properties of a session-scoped user object for null values to detect a session timeout.)&lt;/p&gt;

&lt;p&gt;But what if the application does not handle its own authentication?  Suppose the application server is configured with a JAAS LoginModule and the web application is configured to use basic authentication?  The user principal is now part of the request.  It could be stored in the session, but the application is completely unaware of when authentication occurs and does not control the initial page the user sees.  (The user can navigate to any URI to trigger authentication and will be served that URI if authenticated.)  Worse, authentication is not tied to the session, so the session can timeout several times before the user is actually &quot;logged out&quot; (by closing the browser.)&lt;/p&gt;

&lt;p&gt;So if JSF creates session-scoped managed beans on demand, how does one detect whether the bean was just created?  One approach would be to assume that if certain properties in the session scoped bean are null then the bean hasn&apos;t been properly initialized and must be new.  (A better way of looking at this is if a certain property is null then the session bean is in an invalid state, and the user must restart a transaction.)  This might work, but it would require manipulation of properties that may not have anything to do with the application, and will most likely result in a kludgy workaround.&lt;/p&gt;

&lt;p&gt;And supposing that a session timeout can be detected, where should it be detected?  How should it be handled?  Ideally the user should be redirected to a &quot;timeout&quot; page and be given the ability to return to a stable state.  Can this be accomplished using a filter?&lt;/p&gt;

&lt;p&gt;Using filters in JSF is problematic for several reasons.  First, before processing the filter chain there is no FacesContext.  On the request side, filters are invoked before FacesServlet, so there is no reasonable expectation that a FacesContext or any of its facilities will be available.  Detecting timeouts on the response side is useless, because by then the application has barfed with all kinds of NullPointerExceptions due to the timeout.  Finally, filters operate on ServletRequest and ServletResponse, so there are all kinds of casts and checks that have to be made before HTTP properties can be used.  Filters are brittle for HTTP applications in general and for JSF applications in particular.&lt;/p&gt;

&lt;p&gt;A JSF PhaseListener provides more granular control over the JSF lifecycle, and, more importantly, a FacesContext.  The session timeout needs to be detected as early as possible, so the detection code should be implemented during the RESTORE_VIEW phase in the beforePhase method:&lt;/p&gt;

&lt;b&gt;faces-config.xml&lt;/b&gt;
&lt;div class=&quot;code&quot;&gt;&amp;lt;faces-config&amp;gt;
    &amp;lt;lifecycle&amp;gt;
        &amp;lt;phase-listener&amp;gt;
            SessionTimeoutPhaseListener
        &amp;lt;/phase-listener&amp;gt;
    &amp;lt;/lifecycle&amp;gt;
&amp;lt;/faces-config&amp;gt;
&lt;/div&gt;

&lt;br&gt;
&lt;b&gt;SessionTimeoutPhaseListener.java&lt;/b&gt;
&lt;div class=&quot;code&quot;&gt;public class SessionTimeoutPhaseListener {
    public void beforePhase(PhaseEvent event) {
        // Session detection code goes here
    }

    public void afterPhase(PhaseEvent event) {
        // Do nothing
    }

    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }
}
&lt;/div&gt;

&lt;p&gt;Session-scope managed beans are created on demand, but JSF still provides control over whether a session is instantiated.  The getSession(boolean) method of ExternalContext will return null if there is no session:&lt;/p&gt;

&lt;b&gt;SessionTimeoutPhaseListener.java&lt;/b&gt;
&lt;div class=&quot;code&quot;&gt;public class SessionTimeoutPhaseListener {
    public void beforePhase(PhaseEvent event) {
        FacesContext facesCtx = event
            .getFacesContext();
        ExternalContext extCtx = facesCtx
            .getExternalContext();
        HttpSession session = (HttpSession)extCtx
            .getSession(false);
        
        boolean newSession = (session == null)
            || (session.isNew());
    }

    public void afterPhase(PhaseEvent event) {
        // Do nothing
    }

    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }
}
&lt;/div&gt;

&lt;p&gt;But there is one problem with this approach.  On the first request to the application, there is no session.  The user shouldn&apos;t be presented with a timeout message the first time he accesses the application.  Note that the only time it really matters whether a user&apos;s session has timed out is when a form is posted back to the application and there is no backing bean property to update or action method to invoke.  (Generally speaking, the application will barf during the APPLY_REQUEST_VALUES or UPDATE_MODEL_VALUES phases before it even gets to INVOKE_APPLICATION or RENDER_RESPONSE.)  So whether the request is a postback can be approximated by determining whether there are any request parameters:&lt;/p&gt;

&lt;b&gt;SessionTimeoutPhaseListener.java&lt;/b&gt;
&lt;div class=&quot;code&quot;&gt;public class SessionTimeoutPhaseListener {
    public void beforePhase(PhaseEvent event) {
        FacesContext facesCtx = event
            .getFacesContext();
        ExternalContext extCtx = facesCtx
            .getExternalContext();
        HttpSession session = (HttpSession)extCtx
            .getSession(false);
        
        boolean newSession = (session == null)
            || (session.isNew());
        boolean postback =
            !extCtx.getRequestParameterMap().isEmpty();
        boolean timedout = postback &amp;&amp; newSession;
        if(timedout) {
            // Handle timeout
        }
    }

    public void afterPhase(PhaseEvent event) {
        // Do nothing
    }

    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }
}
&lt;/div&gt;

&lt;p&gt;Finally, once a timeout has been detected, something has to happen.  The ViewHandler can be used to render a timeout page and end the request:&lt;/p&gt;

&lt;b&gt;SessionTimeoutPhaseListener.java&lt;/b&gt;
&lt;div class=&quot;code&quot;&gt;public class SessionTimeoutPhaseListener {
    public void beforePhase(PhaseEvent event) {
        FacesContext facesCtx = event
            .getFacesContext();
        ExternalContext extCtx = facesCtx
            .getExternalContext();
        HttpSession session = (HttpSession)extCtx
            .getSession(false);
        
        boolean newSession = (session == null)
            || (session.isNew());
        boolean postback = !extCtx
            .getRequestParameterMap().isEmpty();
        boolean timedout = postback &amp;&amp; newSession;
        if(timedout) {
            Application app = facesCtx.getApplication();
            ViewHandler viewHandler = app.getViewHandler();
            UIViewRoot view = viewHandler.createView(
                facesCtx,
                &quot;/sessionTimeout.xhtml&quot;);
            facesCtx.setViewRoot(view);
            facesCtx.renderResponse();
            try {
                viewHandler.renderView(facesCtx, view);
                facesCtx.responseComplete();
            } catch(Throwable t) {
                throw new FacesException(
                    &quot;Session timed out&quot;, t);
            }
        }
    }

    public void afterPhase(PhaseEvent event) {
        // Do nothing
    }

    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }
}
&lt;/div&gt;

&lt;p&gt;Note that renderView and responseComplete must be invoked to prevent the JSF Lifecycle from continuing on with the RESTORE_VIEW processing, which will cause the originally requested page to be used instead, which obviates any of the work done in the PhaseListener.&lt;/p&gt;</description>
  <comments>http://jsweetland.livejournal.com/3229.html</comments>
  <category>jsf</category>
  <lj:security>public</lj:security>
  <lj:reply-count>11</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/2897.html</guid>
  <pubDate>Sun, 24 Dec 2006 02:54:30 GMT</pubDate>
  <title>TabbedPane Facelets Support</title>
  <link>http://jsweetland.livejournal.com/2897.html</link>
  <description>&lt;p&gt;I improved Facelets support by adding bean properties to UITabbedPane and UITab instead of relying on attributes (although TabbedPaneTag and TabTag still access the properties through the attributes map using ComponentUtil).  This should get rid of the &quot;attribute XXX not found&quot; warnings Facelets generates when it can&apos;t find bean properties and sets attributes instead.&lt;/p&gt;

&lt;p&gt;I also added some code to delay updating the selected tab until the render response phase.  Switching at the end of the APPLY_REQUEST_VALUES phase (in the &lt;code&gt;decode&lt;/code&gt; method) can cause problems during PROCESS_UPDATES and PROCESS_VALIDATIONS, especially if Hibernate is involved.&lt;/p&gt;

&lt;p&gt;This is probably stable enough to start tracking releases . . . here is release 1 build 1 (r1b1):&lt;/p&gt;

&lt;a href=&quot;http://bellsouthpwp2.net/s/w/sweetlandj/sweetfaces_r1b1.tar.gz&quot;&gt;sweetfaces_r1b1.tar.gz&lt;/a&gt;</description>
  <comments>http://jsweetland.livejournal.com/2897.html</comments>
  <category>jsf</category>
  <category>sweetfaces</category>
  <category>facelets</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/2741.html</guid>
  <pubDate>Tue, 19 Dec 2006 02:45:34 GMT</pubDate>
  <title>TabbedPane Bug Fixes</title>
  <link>http://jsweetland.livejournal.com/2741.html</link>
  <description>&lt;p&gt;I found and fixed a couple pretty serious bugs in the &lt;code&gt;processDecodes&lt;/code&gt; and &lt;code&gt;saveDescendentState&lt;/code&gt; methods of &lt;code&gt;UITabbedPane&lt;/code&gt;.  These bugs resulted in the following behavior:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;&lt;code&gt;ValueChangeListener&lt;/code&gt;s, converters, and validation listeners were applied to the new tab instead of the tab that was just visible, which mean:
  &lt;ul&gt;
   &lt;li&gt;Events do not fire correctly&lt;/li&gt;
   &lt;li&gt;Request values are not applied correctly&lt;/li&gt;
   &lt;li&gt;Hibernate LazyInitializationExceptions if your tabs are backed by lazy loading entities&lt;/li&gt;
  &lt;/ul&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;code&gt;EditableValueHolder&lt;/code&gt; value bindings were evaluated during APPLY REQUEST VALUES, which causes:
  &lt;ul&gt;
   &lt;li&gt;Hibernate LazyInitializationExceptions if your tabs are backed by lazy loading entities&lt;/li&gt;
   &lt;li&gt;Unpredictable results (when combined with the above behavior)&lt;/li&gt;
  &lt;/ul&gt;
 &lt;/li&gt;
 &lt;li&gt;Value binding expressions to be stored as local values, thus preventing evaluation after INVOKE APPLICATION&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These have all been resolved with some very minor changes to code.  Additionally, I&apos;ve added some static methods to &lt;code&gt;UITabbedPane&lt;/code&gt;, &lt;code&gt;findTabbedPaneAncestor&lt;/code&gt; and &lt;code&gt;findTabbedPaneDescendent&lt;/code&gt;, that are useful for obtaining a reference to an enclosing or enclosed &lt;code&gt;UITabbedPane&lt;/code&gt; component (since component binding is not yet available).  I&apos;ve also added the ability to set the selected tab index programmatically via a new &lt;code&gt;setSelectedTabIndex&lt;/code&gt; method on &lt;code&gt;UITabbedPane&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The distribution package has been updated.  It can be found here:&lt;/p&gt;

&lt;a href=&quot;http://bellsouthpwp2.net/s/w/sweetlandj/sweetfaces.tar.gz&quot;&gt;sweetfaces.tar.gz&lt;/a&gt;

&lt;p&gt;The next update will improve facelets support by adding true property accessors to &lt;code&gt;UITabbedPane&lt;/code&gt; and &lt;code&gt;UITab&lt;/code&gt; to avoid &quot;attribute XXX not found&quot; warnings, and by removing the &quot;Invalid child component of UITabbedPane&quot; messages (which happen as a result of the UIInstruction components inserted by facelets).&lt;/p&gt;</description>
  <comments>http://jsweetland.livejournal.com/2741.html</comments>
  <category>jsf</category>
  <category>hibernate</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/2475.html</guid>
  <pubDate>Thu, 30 Nov 2006 21:00:51 GMT</pubDate>
  <title>Hibernate Backref</title>
  <link>http://jsweetland.livejournal.com/2475.html</link>
  <description>&lt;p&gt;Under certain circumstances Hibernate will issue the following error:&lt;/p&gt;

&lt;div class=&quot;code&quot;&gt;
org.hibernate.PropertyValueException: not-null property references a null or transient value: foo.Bar._barsBackref
        at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
        at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:265)
        at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:167)
        at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:114)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
        at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
        at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
        at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
        at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:524)
        at org.hibernate.impl.SessionImpl.save(SessionImpl.java:514)
        at org.hibernate.impl.SessionImpl.save(SessionImpl.java:510)
        ...
&lt;/div&gt;

&lt;p&gt;This happens when:&lt;p&gt;

&lt;ul&gt;
&lt;li&gt;There two or more entities have a collection of &lt;code&gt;foo.Bar&lt;/code&gt;s; and&lt;/li&gt;
&lt;li&gt;The collection mappings are &lt;code&gt;inverse=&quot;false&quot;&lt;/code&gt;; and&lt;/li&gt;
&lt;li&gt;The collection associations all map to the same table; and&lt;/li&gt;
&lt;li&gt;The association of at least one of those entities is &lt;code&gt;not-null=&quot;true&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, suppose the following mappings:&lt;/p&gt;

&lt;b&gt;Foo.hbm.xml&lt;/b&gt;
&lt;div class=&quot;code&quot;&gt;
&amp;lt;!DOCTYPE hibernate-mapping PUBLIC
    &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;
    &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&amp;gt;
    
&amp;lt;hibernate-mapping package=&quot;foo&quot; schema=&quot;foo&quot;&amp;gt;
 &amp;lt;class name=&quot;Foo&quot; table=&quot;foo&quot;&amp;gt;
  &amp;lt;id name=&quot;id&quot; column=&quot;foo_id&quot; unsaved-value=&quot;null&quot;&amp;gt;
   &amp;lt;generator class=&quot;native&quot;&amp;gt;
    &amp;lt;param name=&quot;sequence&quot;&amp;gt;sq_foos&amp;lt;/param&amp;gt;
   &amp;lt;
  &amp;lt;/id&amp;gt;
  &amp;lt;version name=&quot;version&quot;/&amp;gt;
  &amp;lt;set name=&quot;bars&quot; table=&quot;foo_bar&quot; cascade=&quot;all-delete-orphan&quot; lazy=&quot;true&quot;&amp;gt;
   &amp;lt;key column=&quot;foo_id&quot; not-null=&quot;true&quot;/&amp;gt;
   &amp;lt;many-to-many class=&quot;foo.Bar&quot; column=&quot;bar_id&quot;/&amp;gt;
  &amp;lt;/class&amp;gt;
&amp;lt;/hibernate-mapping&amp;gt;
&lt;/div&gt;

&lt;b&gt;Oof.hbm.xml&lt;/b&gt;
&lt;div class=&quot;code&quot;&gt;
&amp;lt;!DOCTYPE hibernate-mapping PUBLIC
    &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot;
    &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;&amp;gt;
    
&amp;lt;hibernate-mapping package=&quot;oof&quot; schema=&quot;foo&quot;&amp;gt;
 &amp;lt;class name=&quot;Oof&quot; table=&quot;oof&quot;&amp;gt;
  &amp;lt;id name=&quot;id&quot; column=&quot;oof_id&quot; unsaved-value=&quot;null&quot;&amp;gt;
   &amp;lt;generator class=&quot;native&quot;&amp;gt;
    &amp;lt;param name=&quot;sequence&quot;&amp;gt;sq_oofs&amp;lt;/param&amp;gt;
   &amp;lt;
  &amp;lt;/id&amp;gt;
  &amp;lt;version name=&quot;version&quot;/&amp;gt;
  &amp;lt;set name=&quot;bars&quot; table=&quot;oof_bar&quot; cascade=&quot;all-delete-orphan&quot; lazy=&quot;true&quot;&amp;gt;
   &amp;lt;key column=&quot;oof_id&quot; not-null=&quot;true&quot;/&amp;gt;
   &amp;lt;many-to-many class=&quot;foo.Bar&quot; column=&quot;bar_id&quot;/&amp;gt;
  &amp;lt;/class&amp;gt;
&amp;lt;/hibernate-mapping&amp;gt;
&lt;/div&gt;

&lt;p&gt;Here we have two classes, Foo and Oof, that hava a many-to-many association to Bar.  (A common scenario would be to have Account and Order entities that both have many-to-many associations with a Contact entity.)&lt;/p&gt;

&lt;p&gt;What happens is that somehow in Hibernate these two mappings get coalesced into a single &quot;bars&quot; persister.  (I suspect this is because they are the same class mapped to the same table.)  This persister tracks all of the properties in Bar plus backrefs (back references) for each of the entities that contain &quot;bars&quot;.  In the above example there would be two additional values, _fooBackref and _barBackref.&lt;/p&gt;

&lt;p&gt;During a flush operation, Hibernate checks nullability of all of these values, including the backrefs.   It checks all of the backrefs, regardless of what the owning entity is.  If we&apos;re saving a Foo with a bunch of Bars in it, then the _oofBackref would necessarily be null and would fail the check, resulting in the stack trace above.&lt;/p&gt;

&lt;p&gt;There are a couple of ways to work around this issue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove &lt;code&gt;not-null=&quot;true&quot;&lt;/code&gt; from all collection associations; or&lt;/li&gt;
&lt;li&gt;Make the collection mappings bidirectional with &lt;code&gt;inverse=&quot;true&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the case of many-to-many associations the first option isn&apos;t a problem, since many-to-many inserts must happen after the inserts on both sides of the associations, meaning the key values will never be null anyway.  (I&apos;ve only ever encountered this problem in many-to-many scenarios.)  The second solution may work better for one-to-many associations.&lt;/p&gt;</description>
  <comments>http://jsweetland.livejournal.com/2475.html</comments>
  <category>hibernate</category>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/2169.html</guid>
  <pubDate>Wed, 22 Nov 2006 01:24:43 GMT</pubDate>
  <title>TabbedPane Updates</title>
  <link>http://jsweetland.livejournal.com/2169.html</link>
  <description>&lt;p&gt;Fixed numerous issues with the TabbedPane and added several enhancements:&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;Changed processDecodes to operate only on the active tab, not all tabs&lt;/li&gt;
 &lt;li&gt;Fixed bug that caused action and actionListener methods to fire on every postback&lt;/li&gt;
 &lt;li&gt;Added missing &quot;rendered&quot; attribute for tab in the TLD&lt;/li&gt;
 &lt;li&gt;Tabs can now be disabled (rendered but not clickable)&lt;/li&gt;
 &lt;li&gt;Different styles and classes can now be applied to individual tabs&lt;/li&gt;
 &lt;li&gt;Tabs can now be images&lt;/li&gt;
 &lt;li&gt;Reduced debug logging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Updated distribution files are &lt;a href=&quot;http://bellsouthpwp2.net/s/w/sweetlandj/sweetfaces.tar.gz&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
  <comments>http://jsweetland.livejournal.com/2169.html</comments>
  <category>jsf</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/1963.html</guid>
  <pubDate>Fri, 10 Nov 2006 01:30:59 GMT</pubDate>
  <link>http://jsweetland.livejournal.com/1963.html</link>
  <description>&lt;p&gt;Added &lt;a href=&quot;https://facelets.dev.java.net/&quot;&gt;Facelets&lt;/a&gt; support to the tabbed pane components.  If you aren&apos;t using Facelets, then you should be.&lt;/p&gt;

&lt;p&gt;Updated binaries and source are here:&lt;/p&gt;

&lt;a href=&quot;http://bellsouthpwp2.net/s/w/sweetlandj/sweetfaces.tar.gz&quot;&gt;sweetfaces.tar.gz&lt;/a&gt;</description>
  <comments>http://jsweetland.livejournal.com/1963.html</comments>
  <category>jsf</category>
  <category>facelets</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/1659.html</guid>
  <pubDate>Tue, 31 Oct 2006 03:46:01 GMT</pubDate>
  <title>Tabbed Pane Component</title>
  <link>http://jsweetland.livejournal.com/1659.html</link>
  <description>&lt;p&gt;A while back I spent a little time digging around for a JSF tabbed pane component for a project I was working on.  In this particular project, there were views in which there were a fixed number of tabs and also views in which I need to dynamically generate a set of tabs from a list of objects.  I also needed the ability to render the tabs on top or on the right.  I didn&apos;t find any components that met this criteria, so I wrote my own modeled after the UIData component in the JSF-RI.&lt;/p&gt;

&lt;p&gt;The result is actually two components that operate in tandem similar to dataTable and column.  The tabbedPan component sets up the context and visual aspects of the tabbed pane, and the tab components represent the individual tabs.  There are main modes of operation: static or dynamic.  In the former, the value of the tabbedPane component is empty.  Nested within the tabbedPane is a tab component for each tab.  Each tab is displayed only once and the number or arrangement of tabs does not change.&lt;/p&gt;

&lt;p&gt;In the dynamic mode, the value attribute of the tabbedPane component is an EL expression that references a Collection, Iterator, Enumeration, or array, and the var attribute is the name of the variable that aliases each element in the value expression (just like a dataTable).  A tab component is nested inside the tabbedPane and functions like a column in a dataTable--a new tab is rendered for each element in the value expression.  (You can actually nest more than one tab component inside the tabbedPane.  The result is that all of the nested tab components are rendered for each element for a total of &lt;i&gt;n&lt;/i&gt; X &lt;i&gt;m&lt;/i&gt; tabs, where   &lt;i&gt;n&lt;/i&gt; is the number of elements in the value expression and &lt;i&gt;m&lt;/i&gt; is the number of nested tab components.)&lt;/p&gt;

&lt;p&gt;The tabbedPane also allows the designer to specify an orientation, so that the tabs are rendered on the left, top, right, or bottom.  There are numerous attributes for customizing the styles used to render active and inactive tabs, making the presentation fully customizable.&lt;/p&gt;

&lt;p&gt;Finally, you can add action or actionListener methods on the tabbedPane to invoke custom code when a tab is clicked.  (The tabbed pane handles its own state, but this might be a useful hook for incremental loading of data.)&lt;/p&gt;

&lt;b&gt;Examples&lt;/b&gt;
&lt;div class=&quot;code&quot;&gt;&amp;lt;%@taglib prefix=&quot;f&quot; uri=&quot;http://java.sun.com/jsf/core&quot;%&amp;gt;
&amp;lt;%@taglib prefix=&quot;h&quot; uri=&quot;http://java.sun.com/jsf/html&quot;%&amp;gt;
&amp;lt;%@taglib prefix=&quot;s&quot; uri=&quot;sweetfaces&quot;%&amp;gt;

&amp;lt;h1&amp;gt;Static Tabbed Pane&amp;lt;h1&amp;gt;
&amp;lt;s:tabbedPane layout=&quot;left&quot;&amp;gt;
    &amp;lt;s:tab name=&quot;World&quot;&amp;gt;&amp;lt;%include file=&quot;world.jsp&quot;%&amp;gt;&amp;lt;/s:tab&amp;gt;
    &amp;lt;s:tab name=&quot;US&quot;&amp;gt;&amp;lt;%include file=&quot;us.jsp&quot;%&amp;gt;&amp;lt;/s:tab&amp;gt;
    &amp;lt;s:tab name=&quot;Sports&quot;&amp;gt;&amp;lt;%include file=&quot;sports.jsp&quot;%&amp;gt;&amp;lt;/s:tab&amp;gt;
    &amp;lt;s:tab name=&quot;Weather&quot;&amp;gt;&amp;lt;%include file=&quot;weather.jsp&quot;%&amp;gt;&amp;lt;/s:tab&amp;gt;
    &amp;lt;s:tab name=&quot;Entertainment&quot;&amp;gt;&amp;lt;%include file=&quot;entertainment.jsp&quot;%&amp;gt;&amp;lt;/s:tab&amp;gt;
    &amp;lt;s:tab name=&quot;Business&quot;&amp;gt;
        &amp;lt;h2&amp;gt;This is the business section . . . &amp;lt;h2&amp;gt;
        &amp;lt;p&amp;gt;Foo . . . &amp;lt;p&amp;gt;
    &amp;lt;/s:tab&amp;gt;
&amp;lt;/s:tabbedPane&amp;gt;

&amp;lt;h1&amp;gt;Static Tabbed Pane&amp;lt;h1&amp;gt;
&amp;lt;s:tabbedPane layout=&quot;left&quot; value=&quot;#{news.sections}&quot; var=&quot;section&quot;&amp;gt;
    &amp;lt;s:tab name=&quot;#{section.title}&quot; page=&quot;#{section.url}&quot;/&amp;gt;
&amp;lt;/s:tabbedPane&amp;gt;
&lt;/div&gt;

&lt;b&gt;Download&lt;/b&gt;

&lt;p&gt;&lt;a href=&quot;http://bellsouthpwp2.net/s/w/sweetlandj/sweetfaces.tar.gz&quot;&gt;sweetfacs.tar.gz&lt;/a&gt; 1.877 MB (Source and binaries)&lt;/p&gt;</description>
  <comments>http://jsweetland.livejournal.com/1659.html</comments>
  <category>jsf</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/1335.html</guid>
  <pubDate>Tue, 17 Oct 2006 23:41:20 GMT</pubDate>
  <title>Java 5 Generics, Polymorphism, and Hibernate</title>
  <link>http://jsweetland.livejournal.com/1335.html</link>
  <description>&lt;p&gt;I ran into an interesting problem today while working with Hibernate.  After loading an object graph and committing the session (with no modifications to the object graph) I noticed that Hibernate was issuing updates and deletes similar to the following:&lt;/p&gt;

&lt;div class=&quot;code&quot;&gt;update &lt;i&gt;my_table&lt;/i&gt; set &lt;i&gt;fk_column&lt;/i&gt;=null where &lt;i&gt;id_column&lt;/i&gt;=?
delete from &lt;i&gt;my_table&lt;/i&gt; where &lt;i&gt;id_column&lt;/i&gt;=?
&lt;/div&gt;

&lt;p&gt;I also began to notice sporadic occurrences of the following error:&lt;/p&gt;

&lt;div class=&quot;code&quot;&gt;org.hibernate.HibernateException: A collection with cascade=&quot;all-delete-orphan&quot; was
no longer referenced by the owning entity instance: &lt;i&gt;my.package.Class.collectionProperty&lt;/i&gt;
&lt;/div&gt;

&lt;p&gt;The properties referenced in the HibernateExceptions were the same properties associated with the updates and deleted.  The root cause seems to have something to do with the fact that these properties were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inherited from a base class&lt;li&gt;
&lt;li&gt;Prototyped using generics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The base class was something similar to this:&lt;/p&gt;

&lt;div class=&quot;code&quot;&gt;public class EntityWithReferences&lt;t extends=&quot;extends&quot; reference=&quot;Reference&quot;&gt; extends Entity {
    protected Set&lt;t&gt; _references = new LinkedHashSet&lt;t&gt;();

    public Set&lt;t&gt; getReferences() {
        return _references;
    }

    public void setReferences(Set&lt;t&gt; references) {
        _references = references;
    }

    public void addReference(T reference) {
        if(reference != null) _references.add(reference);
    }

    public Set&lt;t&gt; getReferences(String system) {
        Set&lt;t&gt; sysRefs = new LinkedHashSet&lt;t&gt;();
        for(T reference: _references) {
            if(reference.getSystem().equals(system)) {
                sysRefs.add(reference);
            }
        }
        return sysRefs;
    }

    // Other common reference behavior
}
&lt;/div&gt;

&lt;p&gt;And my subclasses were something like this:&lt;/p&gt;

&lt;div class=&quot;code&quot;&gt;public class Account extends EntityWithReferences&lt;accountreference&gt; {
    // Account properties and behavior
}
&lt;/div&gt;

&lt;p&gt;Naturally each subclass has its own corresponding subclass of Reference, hence the generics.  What I found though is that somehow Hibernate thinks that these inherited collections are not associating with the &quot;owning entity&quot; (the subclasses of EntityWithReferences).  By getting rid of the generic base class and moving the reference behavior into the subclasses, all of the symptoms disappeared.  The resulting subclasses now look something like this:&lt;/p&gt;

&lt;div class=&quot;code&quot;&gt;public class Account extends Entity {
    public Set&lt;accountreference&gt; _references = new LinkedHashSet&lt;accountreference&gt;();

    public Set&lt;accountreference&gt; getReferences() {
        return _references;
    }

    public void setReferences(Set&lt;accountreferences&gt; references) {
        _references = references;
    }

    public void addReference(AccountReference reference) {
        if(reference != null) _references.add(reference);
    }

    public Set&lt;accountreference&gt; getReferences(String system) {
        Set&lt;accountreference&gt; sysRefs = new LinkedHashSet&lt;accountreference&gt;();
        for(AccountReference reference: _references) {
            if(reference.getSystem().equals(system)) {
                sysRefs.add(reference);
            }
        }
        return sysRefs;
    }

    // Other reference behavior

    // Account properties and behavior
}
&lt;/div&gt;

&lt;p&gt;This isn&apos;t ideal, as now I have to carry all of this biolerplate code around for reference handling, but it does solve my immediate problems.  Here&apos;s hoping that this will save someone else a lot of time.&lt;/p&gt;</description>
  <comments>http://jsweetland.livejournal.com/1335.html</comments>
  <category>hibernate</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/1110.html</guid>
  <pubDate>Sun, 13 Nov 2005 03:01:26 GMT</pubDate>
  <title>&quot;/usr/bin/ld: Undefined Symbol&quot; on Mac OS</title>
  <link>http://jsweetland.livejournal.com/1110.html</link>
  <description>&lt;p&gt;Just ran across a really annoying quirk in the Mac OS gcc linker.  The following makefile failed with numerous &quot;undefined symbols&quot; even though I was linking to the correct libraries (or so I thought):&lt;/p&gt;

&lt;div class=&quot;code&quot;&gt;CFLAGS=-g -Wall -I${PVM_ROOT}/include/
LDFLAGS=-L${PVM_ROOT}/lib/${PVM_ARCH}/ -lpvm3

all: clean problem1_pvm MatrixTest

clean:
        rm -f *.o
        rm -f problem1_pvm

problem1_pvm: problem1_pvm.o Matrix.o Exception.o
        $(CC) $(LDFLAGS) -o $@ problem1_pvm.o Matrix.o Exception.o

MatrixTest: MatrixTest.o Matrix.o Exception.o
        $(CC) $(LDFLAGS) -o $@ MatrixTest.o Matrix.o Exception.o

problem1_pvm.o: problem1_pvm.c problem1_pvm.h
        $(CC) $(CFLAGS) -o $@ -c problem1_pvm.c

MatrixTest.o: MatrixTest.c
        $(CC) $(CFLAGS) -o $@ -c MatrixTest.c

Matrix.o: Matrix.c Matrix.h
        $(CC) $(CFLAGS) -o $@ -c Matrix.c

Exception.o: Exception.c Exception.h
        $(CC) $(CFLAGS) -o $@ -c Exception.c
&lt;/div&gt;

&lt;p&gt;The problem was that I had $(LDFLAGS) before the object files in command line.  It has something to do with the Mac OS gcc being a single-pass linker or something.  Anyway, moving $(LDFLAGS) to the end of the line solved the problem:&lt;/p&gt;

&lt;div class=&quot;code&quot;&gt;CFLAGS=-g -Wall -I${PVM_ROOT}/include/
LDFLAGS=-L${PVM_ROOT}/lib/${PVM_ARCH}/ -lpvm3

all: clean problem1_pvm MatrixTest

clean:
        rm -f *.o
        rm -f problem1_pvm

problem1_pvm: problem1_pvm.o Matrix.o Exception.o
        $(CC) -o $@ problem1_pvm.o Matrix.o Exception.o $(LDFLAGS)

MatrixTest: MatrixTest.o Matrix.o Exception.o
        $(CC) -o $@ MatrixTest.o Matrix.o Exception.o $(LDFLAGS)

problem1_pvm.o: problem1_pvm.c problem1_pvm.h
        $(CC) $(CFLAGS) -o $@ -c problem1_pvm.c

MatrixTest.o: MatrixTest.c
        $(CC) $(CFLAGS) -o $@ -c MatrixTest.c

Matrix.o: Matrix.c Matrix.h
        $(CC) $(CFLAGS) -o $@ -c Matrix.c

Exception.o: Exception.c Exception.h
        $(CC) $(CFLAGS) -o $@ -c Exception.c
&lt;/div&gt;</description>
  <comments>http://jsweetland.livejournal.com/1110.html</comments>
  <category>make</category>
  <category>linker</category>
  <category>gcc</category>
  <category>c</category>
  <category>pvm</category>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/863.html</guid>
  <pubDate>Mon, 19 Sep 2005 21:23:10 GMT</pubDate>
  <title>Hibernate Transactions and Units of Work</title>
  <link>http://jsweetland.livejournal.com/863.html</link>
  <description>I won&apos;t go into depth about Hibernate or the design considerations that it brings, as there is ample documentation on the &lt;a href=&quot;http://www.hibernate.org&quot;&gt;Hibernate&lt;/a&gt; web site.  One particularly useful document is &lt;a href=&quot;http://hibernate.org/168.html&quot;&gt;Session and Transaction Scope&lt;/a&gt;, which elucidates on the concepts of application (user) transactions and units of work.  Suffice to say, that having experimented amply with both design patterns, &lt;i&gt;session-per-request&lt;/i&gt; and &lt;i&gt;session-per-application-transaction&lt;/i&gt;, I strongly prefer the former, as it provides a lot more insight and control over when data is persisted.  I find it is much easier and there are far fewer surprises than with long application transactions.&lt;br /&gt;&lt;br /&gt;I would like to note that in most cases there is a very fine line between the &lt;i&gt;session-per-request&lt;/i&gt; pattern and what the author of the above document calls a &lt;i&gt;session-per-operation&lt;/i&gt; anti-pattern.  It is common to load an object into memory in one request and save it in the next request.  Two operations in two requests averages out to be one session per operation.  Because sessions are lightweight and because they cache data I do not consider &lt;i&gt;session-per-operation&lt;/i&gt; to be anti-pattern from any standpoint other than performance, which can be remedied using a second-level cache.  Of course, whenever possible it is always best to group operations in a single unit of work to enhance performance, provided it is convenient and you are not violating any transaction semantics by doing so.&lt;br /&gt;&lt;br /&gt;The most common method for implementing the &lt;i&gt;session-per-request&lt;/i&gt; pattern is to use the &lt;a href=&quot;http://hibernate.org/42.html&quot;&gt;ThreadLocal Session&lt;/a&gt; pattern, which works well in a servlet container using filters, or in a Struts action class.  It does not, however, isolate all of the concerns that are typical of every transaction.  For example, although the commitTransaction method of HibernateUtil will attempt a rollback if the transaction commit fails, it will not attempt a rollback if there is an error prior to the commit, such as when a business exception that occurs mid-transaction.&lt;br /&gt;&lt;br /&gt;The ideal solution would be to isolate those aspects (transaction error handling and recovery) by wrapping the persistence operations with a boilerplate try/catch/finally block.  This could be done by generating proxies for servlets, JSF backing beans, or Struts actions, but there is no support for that at this time.  The Spring framework AOP facilities may be able to accomodate this approach, but I am not familiar with Spring.&lt;br /&gt;&lt;br /&gt;The solution I came up with was to create an abstract class called UnitOfWork with an abstract method named doWork( ) and a final method named execute( ) that wraps doWork( ) with the appropriate error handling logic.  In the request handler methods, anonymous inner classes extending UnitOfWork can be created inline that contain the persistence operation.  Here is the code:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UnitOfWork.java&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;border: 1px solid silver; background: whitesmoke; padding: 5px; font-family: monospace;&quot;&gt;&lt;pre&gt;public abstract class UnitOfWork
{
    private Throwable _transactionException = null;
    private Throwable _commitException = null;
    private Throwable _rollbackException = null;
    private Throwable _closeException = null;
    
    private boolean _committed = false;
    private boolean _rolledBack = false;
    private boolean _closed = false;
    
    protected Session _session = null;
    protected Transaction _transaction = null;
    
    public Throwable getTransactionException( )
    {
        return _transactionException;
    }    
    
    public Throwable getCommitException( )
    {
        return _commitException;
    }
    
    public Throwable getRollbackException( )
    {
        return _rollbackException;
    }
    
    public Throwable getCloseException( )
    {
        return _closeException;
    }
    
    public boolean isCommitted( )
    {
        return _committed;
    }
    
    public boolean isRolledBack( )
    {
        return _rolledBack;
    }
    
    public boolean isClosed( )
    {
        return _closed;
    }
    
    public abstract Object doWork( Object[] arguments )
    throws Throwable;
    
    private final void init( )
    throws Throwable
    {
        _transactionException = null;
        _commitException = null;
        _rollbackException = null;
        _closeException = null;
    
        _committed = false;
        _rolledBack = false;
        _closed = false;
    }
    
    public final Object execute( )
    throws UnitOfWorkException
    {
        return execute( null );
    }
    
    public final Object execute( Object[] arguments )
    throws UnitOfWorkException
    {
        Object returnValue = null;
        try
        {
            _session = HibernateUtil.openSession( );
            _transaction = _session.beginTransaction( );
            init( );
            returnValue = doWork( arguments );
            try
            {
                commit( );
                _committed = true;
            }
            catch( Throwable commitException )
            {
                _commitException = commitException;
            }    
        }
        catch( Throwable transactionException )
        {
            _transactionException = transactionException;
        }
            
        if( !_committed )
        {
            try
            {
                rollback( );
                _rolledBack = true;
            }
            catch( Throwable rollbackException )
            {
                _rollbackException = rollbackException;
            }
        }

        try
        {
            close( );
            _closed = true;
        }
        catch( Throwable closeException )
        {
            _closeException = closeException;
        }
        
        _session = null;
        _transaction = null;
        
        if( !_committed )
        {
            throwException( );
        }
        else if( !_closed )
        {
            logException( );
        }
        return returnValue;
    }
    
    public void commit( )
    throws Throwable
    {
        if( _transaction != null )
        {
            _transaction.commit( );
        }
    }
    
    public void rollback( )
    throws Throwable
    {
        if( _transaction != null )
        {
            _transaction.rollback( );
        }
    }
    
    public void close( )
    throws Throwable
    {
        if( _session != null )
        {
            _session.close( );
        }
    }
    
    private void throwException( )
    throws UnitOfWorkException
    {
        UnitOfWorkException uowe = buildException( );
        if( uowe != null )
        {
            throw uowe;
        }
    }
    
    private UnitOfWorkException buildException( )
    {
        UnitOfWorkException uowe = null;
        if( _transactionException != null )
        {
            uowe = new UnitOfWorkException( this, _transactionException );
        }
        
        if( (_commitException != null) &amp;&amp; (uowe == null) )
        {
            uowe = new UnitOfWorkException( this, _commitException );
        }
        
        if( (_rollbackException != null) &amp;&amp; (uowe == null) )
        {
            uowe = new UnitOfWorkException( this, _rollbackException );
        }
        
        if( (_closeException != null) &amp;&amp; (uowe == null) )
        {
            uowe = new UnitOfWorkException( this, _closeException );
        }
        
        return uowe;
    }
    
    private void logException( )
    {
        UnitOfWorkException uowe = buildException( );
        // Commons logging, J2SE logging, Log4j, or System.out.println here
    }
}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UnitOfWorkException.java&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;border: 1px solid silver; background: whitesmoke; padding: 5px; font-family: monospace;&quot;&gt;&lt;pre&gt;public class UnitOfWorkException
extends RuntimeException
{
    private UnitOfWork _unitOfWork = null;
    
    public void setUnitOfWork( UnitOfWork unitOfWork )
    {
        _unitOfWork = unitOfWork;
    }
    public UnitOfWork getUnitOfWork( )
    {
        return _unitOfWork;
    }
    
    public UnitOfWorkException( )
    {
    }
    
    public UnitOfWorkException( String message )
    {
        super( message );
    }
    
    public UnitOfWorkException( Throwable cause )
    {
        super( cause );
    }
    
    public UnitOfWorkException( String message, Throwable cause )
    {
        super( message, cause );
    }
    
    public UnitOfWorkException( UnitOfWork unitOfWork )
    {
        _unitOfWork = unitOfWork;
    }
    
    public UnitOfWorkException( UnitOfWork unitOfWork, String message )
    {
        super( message );
        _unitOfWork = unitOfWork;
    }
    
    public UnitOfWorkException( UnitOfWork unitOfWork, Throwable cause )
    {
        super( cause );
        _unitOfWork = unitOfWork;
    }
    
    public UnitOfWorkException( UnitOfWork unitOfWork, String message, Throwable cause )
    {
        super( message, cause );
        _unitOfWork = unitOfWork;
    }
    
    public void printStackTrace( PrintStream out )
    {
        printStackTrace( new PrintWriter( out ) );
    }
    
    public void printStackTrace( PrintWriter out )
    {
        super.printStackTrace( out );
        if( _unitOfWork != null )
        {
            if( _unitOfWork.getCommitException( ) != null )
            {
                out.print( &quot;Upon commit: &quot; );
                _unitOfWork.getCommitException( ).printStackTrace( out );
            }

            if( _unitOfWork.getRollbackException( ) != null )
            {
                out.print( &quot;Upon rollback: &quot; );
                _unitOfWork.getRollbackException( ).printStackTrace( out );
            }

            if( _unitOfWork.getCloseException( ) != null )
            {
                out.print( &quot;Upon close: &quot; );
                _unitOfWork.getCloseException( ).printStackTrace( out );
            }
        }
    }
}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And here is an example of how it would be used as an anonymous inner class:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 1&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;border: 1px solid silver; background: whitesmoke; padding: 5px; font-family: monospace;&quot;&gt;&lt;pre&gt;...
    final String itemName = &quot;Example&quot;;
    Item item = (Item)new UnitOfWork( )
    {
        public Object doWork( Object[] arguments )
        throws Throwable
        {
            String name = (String)arguments[0];
            // Create a new ItemDao using the session variable prepared
            // by the UnitOfWork execute( ) method and placed in the
            // _session instance variable of the UnitOfWork class
            return new ItemDao( _session ).getByName( name );
        }
    }.execute( new Object[] { itemName } );
    System.out.println( &quot;My item: &quot; + item );
    ...&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In this example, all of the error handling and recovery has been replaced with an anonymous inner class declaration.  Arguments and return values can be passed to and from the doWork( ) method through the execute( ) method. The only possible exception that can be thrown from execute( ) is a UnitOfWorkException, which has placeholders for exceptions that can occur at all phases of the execute( ) method.  When the method returns, the programmer can be assured that all cleanup has been accomplished and the best possible effort was made to gracefully recover from any errors that might have occurred.  The init( ), commit( ), rollback( ), and close( ) methods can be overridden to perform additional initialization and cleanup operations as needed (file descriptors, Oracle temporary LOBs, etc.)&lt;br /&gt;&lt;br /&gt;Note that outer class instance variables are accessible within inner classes, so we could have changed the code to be like this:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 2&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;border: 1px solid silver; background: whitesmoke; padding: 5px; font-family: monospace;&quot;&gt;&lt;pre&gt;public class MyClass
{
    private Item _item = null;
    private final String _itemName = &quot;Example&quot;;

    ....

    public void myMethod( )
    {
        ...
        new UnitOfWork( )
        {
            public Object doWork( Object[] arguments )
            throws Throwable
            {
                _item = new ItemDao( _session ).getByName( _itemName );
                return null;
            }
        }.execute( );
        System.out.println( &quot;My item: &quot; + item );
        ...
    }
    ...
}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Some notes about this design pattern:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;The transaction and error handling logic operates only on the session created by the execute( ) method&lt;br /&gt;  &lt;ul&gt;&lt;br /&gt;   &lt;li&gt;The code in the doWork( ) method is free to use any available session, or create its own, but doing so circumvents the error handling logic and defeats the purpose of the UnitOfWork class&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;All work should be done using the session object stored in the _session instance variable, either directly or through Data Access Objects (DAOs) that use the session specified by the caller&lt;/li&gt;&lt;br /&gt;  &lt;/ul&gt;&lt;br /&gt; &lt;/li&gt;&lt;br /&gt; &lt;li&gt;There is no need for a filter or other interceptor&lt;/li&gt;&lt;br /&gt; &lt;li&gt;The session and transactions are opened and closed in the execute( ) method.  All initialization and cleanup is transparent to the programmer.&lt;br /&gt;  &lt;ul&gt;&lt;br /&gt;   &lt;li&gt;Lazy associations must be fetched within a UnitOfWork doWork( ) method&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;All objects are detached outside of the UnitOfWork doWork( ) method&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;Changes made to detached objects will not persist unless the objects are explicitly updated or merged&lt;/li&gt;&lt;br /&gt;  &lt;/ul&gt;&lt;br /&gt; &lt;/li&gt;&lt;br /&gt; &lt;li&gt;A UnitOfWork anonymous class be used to implement either the &lt;i&gt;session-per-operation&lt;/i&gt; pattern (or anti-pattern if you like) or the &lt;i&gt;session-per-request&lt;/i&gt; pattern depending on the content of the doWork( ) method.&lt;br /&gt;  &lt;ul&gt;&lt;br /&gt;   &lt;li&gt;The contents of the doWork( ) method can consist of one operation or a hundred, so long as they all belong to one logical database transaction.&lt;/li&gt;&lt;br /&gt;  &lt;/ul&gt;&lt;br /&gt; &lt;/li&gt;&lt;br /&gt; &lt;li&gt;Works well with servlets and Struts&lt;br /&gt;  &lt;ul&gt;&lt;br /&gt;   &lt;li&gt;Servlet class can extend UnitOfWork and implement javax.servlet.Servlet.  The service( ) method of the servlet can perform some initialization and simply call execute( ) when ready (no anonymous inner class required).&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;Struts action classes require anonymous inner classes (or outside helper classes), as Action classes must extend Action, and there may be more than one unit of work if DispatchAction is used.&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;JSF beans should use anonymous inner classes (or outside helper classes) as there will likely be more than one action method per backing bean&lt;/li&gt;&lt;br /&gt;  &lt;/ul&gt;&lt;br /&gt; &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;</description>
  <comments>http://jsweetland.livejournal.com/863.html</comments>
  <category>database</category>
  <category>hibernate</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/723.html</guid>
  <pubDate>Mon, 12 Sep 2005 23:07:55 GMT</pubDate>
  <title>Java Server Faces UISelect Components</title>
  <link>http://jsweetland.livejournal.com/723.html</link>
  <description>The Java Server Faces (JSF) Reference Implementation (RI) ships with pretty spartan implementations of list components.  These include the select, checkbox, and radio button components created by the following tags:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;selectOneListbox&lt;/li&gt;&lt;br /&gt;&lt;li&gt;selectOneMenu&lt;/li&gt;&lt;br /&gt;&lt;li&gt;selectOneRadio&lt;/li&gt;&lt;br /&gt;&lt;li&gt;selectManyCheckbox&lt;/li&gt;&lt;br /&gt;&lt;li&gt;selectManyListbox&lt;/li&gt;&lt;br /&gt;&lt;li&gt;selectManyMenu&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;These components are special in that they allow a user to choose one or more values from a list of pre-defined options.  These options are typically represented with nested selectItem, selectItems, and selectItemGroup tags.  While seemingly straightforward, these tags are very finicky and often cause failures in the Process Validations phase that prevent action methods from being called.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Component and Value Binding&lt;/h3&gt;&lt;br /&gt;The selectOne and selectMany tags can either be bound to a value on the backing bean (via the value attribute) or to a UISelect component (via the binding component).  If bound to a backing bean value, the value must be a List or an array.  Sets are not supported.&lt;br /&gt;&lt;br /&gt;A nested selectItems tag can only be bound to a value; they cannot be bound to a component.  The value they are bound to must be a List of SelectItem or SelectGroup objects; or an array of SelectItems or SelectGroups.  Sets are not supported.&lt;br /&gt;&lt;br /&gt;A selectItem component is not bound to a single value.  Instead, the itemLabel and itemValue attributes are specified using either string literals or Expression Language (EL) expressions to refer to bean variables.  Note that if selectItem tags are chosen over a selectItems tag then the value type is limited to String.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;SelectItem Values&lt;/h3&gt;&lt;br /&gt;SelectItems work best with String values.  However, a SelectItem value can be any type, provided:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;There is a Converter for the type&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The selectItems tag is used and bound to a List or Array of SelectItem or SelectItemGroup objects&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I have had very little luck with either of the following scenarios:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Using nested selectItem tags with string literals and an explicit converter attribute on the enclosing selectOne or selectMany tag&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Using nested selectItem tags with string literals and an explicit converter tag&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Using nested selectItem tags with EL expressions refering to object values in a backing bean&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Using converters registered by ID&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Validation&lt;/h3&gt;&lt;br /&gt;The selectOne and selectMany tags are unique in that they have an implicit validation step that occurs in the Process Validations phase: the value specified in the request must be contained in the list (or array) of SelectItem objects that is associated with the selectOne or selectMany tag.  If the supplied request value is not, then a FacesMessage is queued on the componend with the summary text &quot;Validation Error: Value is not valid&quot; and the Process Validations phase jumps directly to the Render Response phase, bypassing the Invoke Application Phase.&lt;br /&gt;&lt;br /&gt;This can be very tricky, especially if you are using a custom converter, because the validation logic uses the equals( ) method of the object on each element of the List (or array) of SelectItem objects to determine whether the object is contained in the collection.  If the custom converter returns a new object instance, and the object instance does not override the equals( ) method, then this validation will always fail.  The default implementation of equals( ) checks only for instance equality; two different instances of the same class, while logically equal, will not be considered equal unless there is an overridden equals( ) method.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Example: Selectable Domain Objects&lt;/h4&gt;&lt;br /&gt;Suppose there is a table called LIST_ITEM with the columns ID and LABEL.  Through some ORM magic the values in this table can be read into a List of ListItem objects with the properties &quot;id&quot; and &quot;label&quot;.  We would like to render a drop-down list of SelectItems whose values are the ListItem IDs and whose labels are the ListItem labels.  To do so, we have written a ListItemConverter and have registered it to the class ListItem.  The getAsObject( ) method of the converter queries queries the database for a LIST_ITEM row with an ID that is equal to the supplied value.  A new ListItem is created and populated with the values from the ResultSet, and the ListItem is returned from the Converter.&lt;br /&gt;&lt;br /&gt;In this approach, each call to getAsObject produces a new instance.  Therefore it is important to override the equals( ) method of ListItem like so:&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;border: 1px solid silver; background: whitesmoke; padding: 5px; font-family: monospace;&quot;&gt;&lt;pre&gt;public boolean equals( Object o )
{
    if( this == o ) return true;
    if( o == null ) return false;
    if( !(o instanceof ListItem) ) return false;
    ListItem that = (ListItem)o;
    return getID( ).equals( that.getId( ) ); // getLabel( ) could be used if unique
}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This will guarantee that the ListItem created by getAsObject will appear in the collection of SelectItems.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Fail-proof Approach&lt;/h3&gt;&lt;br /&gt;I have used the following design extensively and have had very good success with it:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Ensure there is a Converter implementation for the desired type registered by class&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Bind the selectOne or selectMany tag to a List or object array of the desired type&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use a nested selectItems tag bound to a bean property that returns a List of SelectItems&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In the backing bean property, set the SelectItem values to be objects of the desired type.  Do not convert to a String.  Set the label to be whatever String value is desired.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In the Class specification for the desired type, override the equals method to determine equality based on a unique key, preferrably a secondary key (business key).&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Complete Example&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ListItem.java&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;border: 1px solid silver; background: whitesmoke; padding: 5px; font-family: monospace;&quot;&gt;&lt;pre&gt;public class ListItem
{
    private long _id = -1;
    private String _label = null;

    public void setId( long id )
    {
        _id = id;
    }
    public long getId( )
    {
        return _id;
    }

    public void setLabel( String label )
    {
        _label = label;
    }
    public String getLabel( )
    {
        return _label;
    }

    public boolean equals( Object o )
    {
        if( this == o ) return true;
        if( o == null ) return false;
        if( !(o instanceof ListItem) ) return false;
        ListItem that = (ListItem) that;
        return getId( ) == that.getId( );
    }
}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ListItemConverter.java&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;border: 1px solid silver; background: whitesmoke; padding: 5px; font-family: monospace;&quot;&gt;&lt;pre&gt;public class ListItemConverter
implements Converter
{
    public Object getAsObject( FacesContext context, UIComponent component, String string )
    throws ConverterException
    {
        return new ListItemDao( ).loadById( Integer.parseInt( string ) );
    }

    public String getAsString( FacesContext context, UIComponent component, Object object )
    {
        return String.valueOf( ((ListItem)object).getId( ) );
    } 
}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;BackingBean.java&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;border: 1px solid silver; background: whitesmoke; padding: 5px; font-family: monospace;&quot;&gt;&lt;pre&gt;public class BackingBean
{
    private ListItem[] _selectedListItems = null;

    public List getListItemSelectItems( )
    {
        List listItemSelectItems = new List( );
        List listItems = new ListItemDao( ).loadAll( );
        for( Iterator liIter = listItems.iterator( ); liIter.hasNext( ); )
        {
            ListItem li = (ListItem)liIter.next( );
            listItemSelectItems.add( new SelectItem( li, li.getLabeL( ) );
        } 
        return listItemSelectItems;
    }

    public void setSelectedListItems( ListItem[] selectedListItems )
    {
        _selectedListItems = selectedListItems;
    }
    public ListItem[] getSelectedListItems( )
    {
        return _selectedListItems;
    }
}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;faces-config.xml&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;border: 1px solid silver; background: whitesmoke; padding: 5px; font-family: monospace;&quot;&gt;&lt;pre&gt;...
&amp;lt;converter&amp;gt;
    &amp;lt;converter-for-class&amp;gt;ListItem&amp;lt;/converter-for-class&amp;gt;
    &amp;lt;converter-class&amp;gt;ListItemConverter&amp;lt;/converter-class&amp;gt;
&amp;lt;/converter&amp;gt;
...
&amp;lt;managed-bean&amp;gt;
    &amp;lt;managed-bean-name&amp;gt;backingBean&amp;lt;/managed-bean-name&amp;gt;
    &amp;lt;managed-bean-class&amp;gt;BackingBean&amp;lt;/managed-bean-class&amp;gt;
&amp;lt;/managed-bean&amp;gt;
...&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;example.jsf&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;border: 1px solid silver; background: whitesmoke; padding: 5px; font-family: monospace;&quot;&gt;&lt;pre&gt;...
&amp;lt;h:selectOneMany value=&quot;#{backingBean.selectedListItems}&quot;&amp;gt;
    &amp;lt;f:selectItems value=&quot;#{backingBean.listItemSelectItems}&quot;/&amp;gt;
&amp;lt;/h:selectOneMany&amp;gt;
...&lt;/pre&gt;&lt;/div&gt;</description>
  <comments>http://jsweetland.livejournal.com/723.html</comments>
  <category>jsf</category>
  <lj:security>public</lj:security>
  <lj:reply-count>16</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://jsweetland.livejournal.com/399.html</guid>
  <pubDate>Sat, 03 Sep 2005 04:43:14 GMT</pubDate>
  <title>Hierarchical Navigation in JSF</title>
  <link>http://jsweetland.livejournal.com/399.html</link>
  <description>&lt;i&gt;(Note: I typed this up in TextEdit.  The code provided is for illustration purposes and was not tested.  If there are any errors, please post corrections in the article comments.)&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;One of the biggest problems I encountered when learning Java Server Faces (JSF) was figuring out the best way to navigate from a list of items to a view or edit screen for a particular item in the list.  By &quot;best&quot; I mean one that is in the spirit of the framework and is not difficult to implement or unreadable.  The scenario I will discuss happens pretty frequently in the applications I work with, but it is not specifically addressed in Core Java Server Faces or any of the tutorials I have encountered on the web.&lt;br /&gt;&lt;br /&gt;The setup is this: one page (items.jsp) contains a table with one row per item.  Each row has a button or a link that takes the user to the next page, editItem.jsp, which contains a form allowing the user to view and change the properties for a particular item.  When the editItem.jsp form is submitted, the user is taken back to items.jsp and the changes are visible.  This model can of course be more complex, such as in the case where there is a whole heirarchy of objects (Category -&amp;gt; SubCategory -&amp;gt; Item -&amp;gt; Feature).&lt;br /&gt;&lt;br /&gt;The old way of doing things was to create a servlet (EditItem.java) that:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;looks for a request parameter (&quot;itemId&quot;)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;loads that item from a persistent store&lt;/li&gt;&lt;br /&gt;&lt;li&gt;stores the item in the request or session context&lt;/li&gt;&lt;br /&gt;&lt;li&gt;forwards to editItem.jsp&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Each row of the table in items.jsp would have a link explicitly specifying the GET method parameter &quot;itemId&quot; so that the item ID passed to EditItem.java varies depending on which link (row) is clicked.  A POST method solution can be achieved by using submit inputs in lieu of links and using a Javascript onclick event to populate a hidden form input named &quot;itemId&quot; before the form is submitted (this is, in fact, how Struts implements some of the controls).&lt;br /&gt;&lt;br /&gt;JSF can coexist with servlets, but in using the approach described above I find that most of the application logic ends up taking place in servlets, using JSF only for component binding or backing beans.  It is possible to access the request map through the external context but that is kind of dodgy.  What we would like to do is call a backing bean method and have that method infer which row was clicked on using only JSF components and events.  Other than the request parameter trick, there are a couple good ways to do this.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Component Attributes&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;One approach would be to add an attribute to the &amp;lt;h:commandButton&amp;gt; or &amp;lt;h:commandLink&amp;gt; component and then bind the component to an action listener method on the backing bean.  Note that an action listener method differs from a normal action method in that it is passed an ActionEvent parameter that provides a pointer to the UICommand component that invoked the method.  The attribute, in this case the item ID, can be read from the UICommand component&apos;s attribute map and used to load the appropriate Item.  This item is then stored in another backing bean property, currentItem, so it can be referenced by editItem.jsp.&lt;br /&gt;&lt;br /&gt;This approach has a drawback: your backing bean must be session-scoped.  This means that cleanup may be necessary to prevent a previously selected Item from bleeding over onto another form.  For example, suppose an Item was selected and then edited.  Afterward, the user chooses to create a new item.  If the addItem.jsp page also uses the currentItem property of the backing bean, then it is possible that the addItem.jsp page will show the data for the Item that was just edited.  To prevent this, either create a currentItem property for each page; use separate backing beans; or set currentItem to null whenever changes are committed to the persistent store or abandoned.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Code&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;items.jsp&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;display: block; border: 1px solid silver; background: whitesmoke; padding: 10px; font-family: monospace;&quot;&gt;&lt;br /&gt;&lt;pre&gt;
...
&amp;lt;f:form&amp;gt;
   &amp;lt;h:dataTable value=&quot;#{itemBean.items}&quot; var=&quot;i&quot;&amp;gt;
      &amp;lt;h:column&amp;gt;
         &amp;lt;f:facet name=&quot;header&quot;&amp;gt;&amp;lt;f:verbatim&amp;gt;Name&amp;lt;/f:verbatim&amp;gt;&amp;lt;/f:facet&amp;gt;
         &amp;lt;h:outputText value=&quot;#{i.name}&quot;/&amp;gt;
      &amp;lt;/h:column&amp;gt;
      &amp;lt;h:column&amp;gt;
         &amp;lt;f:facet name=&quot;header&quot;&amp;gt;&amp;lt;f:verbatim&amp;gt;Action&amp;lt;/f:verbatim&amp;gt;&amp;lt;/f:facet&amp;gt;
         &amp;lt;h:commandButton value=&quot;Edit&quot; actionListener=&quot;#{itemsBean.editItem}&quot;&amp;gt;
             &amp;lt;f:attribute name=&quot;itemId&quot; value=&quot;#{i.id}&quot;/&amp;gt;
         &amp;lt;/h:commandButton&amp;gt;
      &amp;lt;/h:column&amp;gt;
   &amp;lt;/h:dataTable&amp;gt;
&amp;lt;/f:form&amp;gt;
...
&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ItemBean.java&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;display: block; border: 1px solid silver; background: whitesmoke; padding: 10px; font-family: monospace;&quot;&gt;&lt;br /&gt;&lt;pre&gt;public class ItemBean
{
    private Item _currentItem = null;
    public void setCurrentItem( Item currentItem )
    {
        _currentItem = currentItem;
    }
    public Item getCurrentItem( )
    {
        return _currentItem;
    }

    public List getItems( )
    {
        return new ItemDao( ).loadAll( );
    }

    public String editItem( ActionEvent event )
    {
        UICommand command = (UICommand)event.getComponent( );
        String itemId = (String)command.getAttributes( ).get( &quot;itemId&quot; );
        Item itemToEdit = new ItemDao( ).loadById( itemId );
        setCurrentItem( itemToEdit );
        return &quot;success&quot;;
    }

    public String saveCurrentItem( )
    {
        new ItemDao( ).save( getCurrentItem( ) );
        setCurrentItem( null );
        return &quot;success&quot;;
    }
}
...
&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;editItem.jsp&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;display: block; border: 1px solid silver; background: whitesmoke; padding: 10px; font-family: monospace;&quot;&gt;&lt;br /&gt;&lt;pre&gt;
...
&amp;lt;h:inputLabel for=&quot;name&quot;&amp;gt;&amp;lt;f:verbatim&amp;gt;Name&amp;lt;/f:verbatim&amp;gt;&amp;lt;/h:inputLabel&amp;gt;
&amp;lt;h:inputText id=&quot;name&quot; value=&quot;#{itemBean.currentItem.name}&quot;/&amp;gt;
&amp;lt;h:commandButton value=&quot;Save&quot; action=&quot;#{itemBean.saveCurrentItem&quot;/&amp;gt;
...
&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Decorators&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;This is a very involved approach.  I prefer it because it makes use of the Inversion of Control (IOC) and offers a very clean delineation between the model (POJO) and view/controller (JSF).  Such a loose coupling of frameworks allows interchangeability of frameworks (JSF, Spring, Hibernate) and offers a clean separation of concerns.&lt;br /&gt;&lt;br /&gt;A &amp;lt;h:dataTable&amp;gt; iterates over a list and assigns each element in the list to a temporary variable (i) that can be used to extract property values specific to each item in a list.  We used that functionality in the previous approach to extract the ID from each item and assign it to an attribute on an action listener method.  That method used the attribute value to load the appropriate Item and initialized the currentItem property of ItemBean for use by editItem.jsp.  In the previous example, all of the &amp;lt;h:commandButton&amp;gt; components were bound to the same method of the session-scoped bean ItemBean.  Instead of binding every &amp;lt;h:commandButton&amp;gt; to the same method, couldn&apos;t they be bound to a method of the temporary variable (#{i.editItem})?&lt;br /&gt;&lt;br /&gt;This has very interesting implications.  If the &amp;lt;commandButton&amp;gt; is bound directly to a method on the Item, then do we still need to pass the itemId?  No, because the method only has access to one Item: the Item that is the object instance the method was invoked on.  &lt;br /&gt;&lt;br /&gt;But does this really solve any problems?  Suppose that the Item object has a method called editThisItem and that every &amp;lt;h:commandButton&amp;gt; is bound to the editThisItem method of a particular Item instance.  The method knows which Item to operate on, and what&apos;s more, it doesn&apos;t need to load it from the persistent store.  All that is left is to navigate to editItem.jsp... so why even bother invoking the method in the first place?&lt;br /&gt;&lt;br /&gt;The problem is that when editItem.jsp loads, it will have nothing to reference.  In the previous approach, a property called currentItem was initialized and referenced by editItem.jsp.  Something similar must be done with this approach--the editThisItem method must store a reference to its Item instance in a managed bean so that it can be used by editItem.jsp.  Here is where it gets involved.&lt;br /&gt;&lt;br /&gt;Three managed beans are needed:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;SessionBean - a session-scoped bean that holds a pointer to the current item&lt;/li&gt;&lt;br /&gt;&lt;li&gt;ItemsBean - a request-scoped bean that contains a list of ItemBeans&lt;/li&gt;&lt;br /&gt;&lt;li&gt;ItemBean - a decorator for a Item instance that exposes action methods.  Also a request-scoped bean used by editItem.jsp.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Both ItemsBean and ItemBean contain a property named sessionBean that stores a reference to the SessionBean instance.  ItemBean also has a propert named item that points to the Item instance it wraps.  Both of these are managed properties that are initialized by the JSF container when the beans are iniitalized.&lt;br /&gt;&lt;br /&gt;The &amp;lt;h:dataTable&amp;gt; in items.jsp iterates over the itemBeans collection of the ItemsBean bean.  The temporary variable stores an ItemBean reference that can be used to refer to the Item that is being wrapped (item) or the action method (editThisItem).  The editThisItem method of ItemBean will initialize the currentItem property of sessionBean.  The editItem.jsp page will use an ItemBean backing bean whose item property will be initialized with the value of currentItem from the sessionBean by the JSF container.&lt;br /&gt;&lt;br /&gt;The sequence of events is this:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;SessionBean instance is created as sessionBean&lt;/li&gt;&lt;br /&gt;&lt;li&gt;ItemsBean instance is created as itemsBean.  itemsBean.sessionBean is initalized with sessionBean.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;itemBeans property is initialized as a List of &lt;i&gt;unmanaged&lt;/i&gt; ItemBean elements&lt;/li&gt;&lt;br /&gt;&lt;li&gt;items.java initializes &amp;lt;h:dataTable&amp;gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&amp;lt;h:commandButton&amp;gt; is clicked&lt;/li&gt;&lt;br /&gt;&lt;li&gt;editThisItem method is invoked.  sessionBean.item is initalized with the Item instance wrapped by the ItemBean decorator.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;ItemBean instance is created as itemBean.  itemBean.sessionBean is initialized with sessionBean.  itemBean.item is initialized with sessionBean.item&lt;/li&gt;&lt;br /&gt;&lt;li&gt;edit.jsp extracts values from and applies values to itemBean.item&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Code&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SessionBean.java&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;display: block; border: 1px solid silver; background: whitesmoke; padding: 5px; font-family: monospace;&quot;&gt;&lt;br /&gt;&lt;pre&gt;public class SessionBean
{
    private Item _currentItem = null;
    public void setCurrentItem( Item currentItem )
    {
        _currentItem = currentItem;
    }
    public Item getCurrentItem( )
    {
        return _currentItem;
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ItemsBean.java&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;display: block; border: 1px solid silver; background: whitesmoke; padding: 10px; font-family: monospace;&quot;&gt;&lt;br /&gt;&lt;pre&gt;public class ItemsBean
{
    private SessionBean _sessionBean = null;
    public void setSessionBean( SessionBean sessionBean )
    {
        _sessionBean = sessionBean;
    }

    public List getItemBeans( )
    {
        List items = new ItemDao( ).loadAll( );
        List itemBeans = new ArrayList( );
        for( Iterator itemIter = items.iterator( ); itemIter.hasNext( ); )
        {
            itemBeans.add( new ItemBean( _sessionBean, (Item)itemIter.next( ) ) );
        }
        return itemBeans;
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ItemBean.java&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;display: block; border: 1px solid silver; background: whitesmoke; padding: 10px; font-family: monospace;&quot;&gt;&lt;br /&gt;&lt;pre&gt;public class ItemBean
{
    private SessionBean _sessionBean = null;
    public void setSessionBean( SessionBean sessionBean )
    {
        _sessionBean = sessionBean;
    }

    private Item _item = null;
    public void setItem( Item item )
    {
        _item = item;
    }
    public Item getItem( )
    {
        return _item;
    }

    public ItemBean( ) { }
    public ItemBean( SessionBean sessionBean, Item item )
    {
        _sessionBean = sessionBean;
        _item = item;
    }

    public String editThisItem( )
    {
        _sessionBean.setCurrentItem( _item );
        return &quot;success&quot;;
    }

    public String removeThisItem( )
    {
        new ItemDao( ).delete( _item );
        return &quot;success&quot;;
    }

    public String saveThisItem( )
    {
        new ItemDao( ).save( _item );
        return &quot;success&quot;;
    }
}
&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;faces-config.xml&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;display: block; border: 1px solid silver; background: whitesmoke; padding: 10px; font-family: monospace;&quot;&gt;&lt;br /&gt;&lt;pre&gt;...
&amp;lt;managed-bean&amp;gt;
    &amp;lt;managed-bean-name&amp;gt;sessionBean&amp;lt;/managed-bean-name&amp;gt;
    &amp;lt;managed-bean-class&amp;gt;SessionBean&amp;lt;managed-bean-class&amp;gt;
    &amp;lt;managed-bean-scope&amp;gt;session&amp;lt;managed-bean-scope&amp;gt;
&amp;lt;managed-bean&amp;gt;
&amp;lt;managed-bean&amp;gt;
    &amp;lt;managed-bean-name&amp;gt;itemsBean&amp;lt;/managed-bean-name&amp;gt;
    &amp;lt;managed-bean-class&amp;gt;ItemsBean&amp;lt;managed-bean-class&amp;gt;
    &amp;lt;managed-bean-scope&amp;gt;request&amp;lt;managed-bean-scope&amp;gt;
    &amp;lt;managed-property&amp;gt;
        &amp;lt;property-name&amp;gt;sessionBean&amp;lt;property-name&amp;gt;
        &amp;lt;property-class&amp;gt;SessionBean&amp;lt;property-class&amp;gt;
        &amp;lt;property-value&amp;gt;#{sessionBean}&amp;lt;property-value&amp;gt;
    &amp;lt;managed-property&amp;gt;
&amp;lt;managed-bean&amp;gt;
&amp;lt;managed-bean&amp;gt;
    &amp;lt;managed-bean-name&amp;gt;itemBean&amp;lt;/managed-bean-name&amp;gt;
    &amp;lt;managed-bean-class&amp;gt;ItemBean&amp;lt;managed-bean-class&amp;gt;
    &amp;lt;managed-bean-scope&amp;gt;request&amp;lt;managed-bean-scope&amp;gt;
    &amp;lt;managed-property&amp;gt;
        &amp;lt;property-name&amp;gt;sessionBean&amp;lt;property-name&amp;gt;
        &amp;lt;property-class&amp;gt;SessionBean&amp;lt;property-class&amp;gt;
        &amp;lt;property-value&amp;gt;#{sessionBean}&amp;lt;property-value&amp;gt;
    &amp;lt;managed-property&amp;gt;
   &amp;lt;managed-property&amp;gt;
        &amp;lt;property-name&amp;gt;item&amp;lt;property-name&amp;gt;
        &amp;lt;property-class&amp;gt;Item&amp;lt;property-class&amp;gt;
        &amp;lt;property-value&amp;gt;#{sessionBean.item}&amp;lt;property-value&amp;gt;
    &amp;lt;managed-property&amp;gt;
&amp;lt;managed-bean&amp;gt;
...
&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;items.jsp&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;display: block; border: 1px solid silver; background: whitesmoke; padding: 10px; font-family: monospace;&quot;&gt;&lt;br /&gt;&lt;pre&gt;...
&amp;lt;f:form&amp;gt;
   &amp;lt;h:dataTable value=&quot;#{itemsBean.itemBeans}&quot; var=&quot;ib&quot;&amp;gt;
      &amp;lt;h:column&amp;gt;
         &amp;lt;f:facet name=&quot;header&quot;&amp;gt;&amp;lt;f:verbatim&amp;gt;Name&amp;lt;/f:verbatim&amp;gt;&amp;lt;/f:facet&amp;gt;
         &amp;lt;h:outputText value=&quot;#{ib.item.name}&quot;/&amp;gt;
      &amp;lt;/h:column&amp;gt;
      &amp;lt;h:column&amp;gt;
         &amp;lt;f:facet name=&quot;header&quot;&amp;gt;&amp;lt;f:verbatim&amp;gt;Action&amp;lt;/f:verbatim&amp;gt;&amp;lt;/f:facet&amp;gt;
         &amp;lt;h:commandButton value=&quot;Edit&quot; actionListener=&quot;#{ib.editThisItem}&quot;/&amp;gt;
      &amp;lt;/h:column&amp;gt;
   &amp;lt;/h:dataTable&amp;gt;
&amp;lt;/f:form&amp;gt;
...
&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;editItem.jsp&lt;/b&gt;&lt;br /&gt;&lt;div style=&quot;display: block; border: 1px solid silver; background: whitesmoke; padding: 10px; font-family: monospace;&quot;&gt;&lt;br /&gt;&lt;pre&gt;...
&amp;lt;h:inputLabel for=&quot;name&quot;&amp;gt;&amp;lt;f:verbatim&amp;gt;Name&amp;lt;/f:verbatim&amp;gt;&amp;lt;/h:inputLabel&amp;gt;
&amp;lt;h:inputText id=&quot;name&quot; value=&quot;#{itemBean.item.name}&quot;/&amp;gt;
&amp;lt;h:commandButton value=&quot;Save&quot; action=&quot;#{itemBean.item.saveThisItem&quot;/&amp;gt;
...
&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;</description>
  <comments>http://jsweetland.livejournal.com/399.html</comments>
  <category>jsf</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
</channel>
</rss>
