<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:series="http://unfoldingneurons.com/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Summa Blog</title>
	
	<link>http://www.summa-tech.com/blog</link>
	<description>Summa Blog</description>
	<pubDate>Wed, 08 Feb 2012 14:53:55 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/summa-tech/LoQU" /><feedburner:info uri="summa-tech/loqu" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Identify the Need for BRMS</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/GGOB33mT0Ig/</link>
		<comments>http://www.summa-tech.com/blog/2012/02/08/identify-the-need-for-brms/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 14:52:58 +0000</pubDate>
		<dc:creator>Via Tsuji</dc:creator>
		
		<category><![CDATA[Process Integration]]></category>

		<category><![CDATA[BA]]></category>

		<category><![CDATA[BEP]]></category>

		<category><![CDATA[BPM]]></category>

		<category><![CDATA[brms]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=4118</guid>
		<description><![CDATA[All technologies go through the life cycle of maturity and adoption. For most technologies, over-enthusiasm or “hype” and subsequent disappointment precedes mainstream adoption and realization of how the technology solves real business problems. Gartner has modeled this evolution in the Hype Cycle and identified distinct key phases (Gartner).

Business Rule Management Systems (BRMS) began the descent towards the “Trough of Disillusionment” in 2011 (Dixon &#38; Jones, 2011), wherein many implementations fail to deliver what businesses expected it could.

The focus of this series is to provide guidelines for truly reaping the benefits of a business rule management system. It clarifies certain implementation steps, debunks unrealistic expectations, and warns of common pitfalls to a BRMS implementation.

BRMS is not a stranger to the Law of the Instrument. It is either misused or overused for problems that could otherwise have been solved by different or simpler solutions. The second part of this series focuses on correctly identifying the need for a BRMS and distinguishing it from similar technologies.  ]]></description>
			<content:encoded><![CDATA[<div class="seriesmeta">This entry is part 2 of 1 in the series <a href="http://www.summa-tech.com/blog/series/reaping-the-benefits-of-brms/"  title="series-316">Reaping the Benefits of BRMS</a></div><p class="MsoNormal">All businesses have policies and rules embedded in their IT systems, but not all businesses require a Business Rule Management System (BRMS) implementation. Though incorrect business rules in BRMS can easily be fixed, it is more complex to rectify a BRMS that was not needed in the first place. Thus, to fully reap the benefits of business rules, first, it is crucial to precisely identify the need of a BRMS in the enterprise – recognize the aspects of the business which validly require a BRMS and distinguish it from other decision management technologies, such as Business Process Management (BPM) software.</p>
<p class="MsoNormal">
<p class="MsoNormal">Enterprises could highly benefit from a BRMS if it is characterized by the following conditions (IBM):</p>
<p class="MsoNormal">
<ul>
<li><strong>Frequent Business Rule Changes.</strong> Rule changes originate from evolving business conditions (e.g. competitive pricing), regulatory amendments (e.g. government compliance laws), and varying organizational practices and policies (e.g. validation and feasibility checks). Organizations with frequent business rule changes are fortunate if modifications to their business policies and/or rules are foreseen and scheduled. However, in reality, this rarely happens. Oftentimes, the necessary changes are not implemented in the required IT systems correctly and/or on-time, risking missed opportunities or regulatory violations. Enabling the LOB to change the rules themselves through a BRMS shortens the release cycle for these changes and helps decrease the risks.</li>
<li><strong>Highly Variable Decision-Making.</strong> Certain business models require customized and/or personalized decisions, specific to locality, product, process or the customer itself (e.g. verification and pricing rules). When embedded in an application, the decision logic for these requirements is complex and even more complex to change and validate. With a BRMS, the organization is equipped with flexible and standard mechanisms for expressing and validating these complex rules.</li>
<li><strong>Enterprise Logic Sharing.</strong> Without a BRMS, business logic that is shared in different applications throughout the organization is either duplicated or embedded in the database. This model works well, until the logic needs to be modified. Logic changes are cumbersome to propagate or are implemented inconsistently. The shared repository and versioning capabilities of a BRMS reduce or eliminate these challenges.</li>
</ul>
<p class="MsoNormal">Another pitfall to properly recognizing the need for a business rule management system is confusing its need for other decision management technologies. Sometimes the business problem requires a BRMS in combination with other systems. Other times, the solution may not need to involve a BRMS at all.</p>
<p class="MsoNormal">Decision management is a “practice of combining software and expertise to automate and improve decision-making within critical business systems”. The core purpose is to “make the best possible decision at the current moment based on data and situational context” (Wilson &amp; Stineman, 2010). Not all decision management scenarios are necessarily a call to action by a business rule management system.</p>
<p class="MsoNormal">The fundamental distinctions of a BRMS from other decision management technologies are determining the decision based on what is “known” (e.g. corporate policies, regulations) and providing the tools to manage and govern those decisions. A BRMS does the following well: (1) standardizing of operational decisions; (2) straight through processing; and (3) decision brokerage (FICO, 2006).</p>
<p class="MsoNormal">However, it does not perform well when the problem involves waiting for human intervention, making asynchronous calls to remote systems or gracefully handling errors and exceptions to other services (Sparkling Logic, 2010). In those instances, look to other decision management technologies:</p>
<table border="1" cellspacing="0" cellpadding="2">
<thead>
<tr>
<td style="color: white; background-color: #b89266;" width="309" valign="top"><strong>Technology</strong></td>
<td style="color: white; background-color: #b89266;" width="489" valign="top"><strong>Description</strong></td>
</tr>
</thead>
<tbody>
<tr>
<td width="309" valign="top"><strong>Business Process Management (BPM)</strong></td>
<td width="489" valign="top">BPM is about &#8220;How it should be carried out?&#8221; It   focuses on (1) automating and standardizing processes, especially   long-running transactions; (2) facilitating collaboration; (3) defining and   managing workflows; (4) monitoring activities; and (5) integration brokerage.   (FICO, 2006)</p>
<p>Though decision-making functions can be embedded in   BPM, it is not always the ideal place for them, particularly when the   decision-making increases in complexity. When the workflow becomes a stack of   spaghetti links, it could indicate the need to integrate the BPM with a BRMS.</td>
</tr>
<tr>
<td width="309" valign="top"><strong>Business Event Processing (BEP)</strong></td>
<td width="489" valign="top">BEP focuses on detecting events and patterns for real-time and   temporal comprehension of how to process the incident. Similar to BPM, it can   be combined with a BRMS for orchestrating business information, actions and   responses.</td>
</tr>
<tr>
<td width="309" valign="top"><strong>Business Analytics (BA)</strong></td>
<td width="489" valign="top">BA involves complex decision-making for different   types of goals: (1) historical insights and predictions; (2) optimization of   resources and values; and (3) tracking and monitoring effectiveness. It is   best used for making decisions with a high degree of uncertainty, such as   what is likely to happen in the future or what is the best solution based on   historical trending.</td>
</tr>
</tbody>
</table>
<p><span><span>Business rule management systems can undeniably benefit enterprises with real business problems associated with highly variable and complex decision logic. </span>Validate the need of the tool in the enterprise before getting caught up in the “hype”. Know the needs of the organization and how a BRMS can fulfill the requirements. </span>Explore other decision management technologies and ensure that a BRMS is the right system for the organization. And reap the benefits of a much needed BRMS implementation!</p>
<p><strong>References</strong></p>
<p class="MsoNormal">Dixon, J., &amp; Jones, T. (2011, July 25) <em>Hype Cycle for Business Process Management, 2011</em>.</p>
<p class="MsoBibliography">FICO. (2006, February 9). <em>Are BPMS and BRMS complementary or not?</em> Retrieved February 17, 2011, from FICO Decision Management Blog: <a href="http://www.edmblog.com/weblog/2006/02/are_bpms_and_br.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.edmblog.com/weblog/2006/02/are_bpms_and_br.html');">http://www.edmblog.com/weblog/2006/02/are_bpms_and_br.html</a></p>
<p>Gartner. (n.d.). <em>Gartner Hype Cycle</em>. Retrieved February 21, 2011, from Gartner:<a href="http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp');">http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp</a></p>
<p class="MsoBibliography">IBM. (n.d.). <em>What is a BRMS?</em> Retrieved February 17, 2011, from IBM: <a href="http://www-01.ibm.com/software/websphere/products/business-rule-management/whatis/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www-01.ibm.com/software/websphere/products/business-rule-management/whatis/');">http://www-01.ibm.com/software/websphere/products/business-rule-management/whatis/</a></p>
<p class="MsoBibliography">Sparkling Logic. (2010, February 16). <em>#1 Pitfall in Decision Management.</em> Retrieved February 18, 2011, from Everything Decision Management, Technically Speaking: <a href="http://techondec.wordpress.com/2010/02/16/1-pitfall-in-decision-management/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://techondec.wordpress.com/2010/02/16/1-pitfall-in-decision-management/');">http://techondec.wordpress.com/2010/02/16/1-pitfall-in-decision-management/</a></p>
<p class="MsoBibliography">
<p class="MsoBibliography">Sparkling Logic. (2010, August 24). <em>Business Rules in or out of BPM?</em> Retrieved February 17, 2011, from Everything Decision Management, Technically Speaking: <a href="http://techondec.wordpress.com/2010/08/24/business-rules-in-or-out-of-bpm/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://techondec.wordpress.com/2010/08/24/business-rules-in-or-out-of-bpm/');">http://techondec.wordpress.com/2010/08/24/business-rules-in-or-out-of-bpm/</a></p>
<p class="MsoBibliography">
<p class="MsoBibliography">Wilson, C., &amp; Stineman, B. (2010, November). <em>Clear up confusion over BRMS, BEP, BA &amp; BPM.</em> Retrieved February 17, 2011, from IBM: <a href="http://www-01.ibm.com/software/solutions/soa/newsletter/nov10/brms.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www-01.ibm.com/software/solutions/soa/newsletter/nov10/brms.html');">http://www-01.ibm.com/software/solutions/soa/newsletter/nov10/brms.html</a></p>
<p class="MsoNormal">
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/GGOB33mT0Ig" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2012/02/08/identify-the-need-for-brms/feed/</wfw:commentRss>
	
		<series:name><![CDATA[Reaping the Benefits of BRMS]]></series:name>
	<feedburner:origLink>http://www.summa-tech.com/blog/2012/02/08/identify-the-need-for-brms/</feedburner:origLink></item>
		<item>
		<title>Top 5 Salesforce Spring ‘12 Release “Likes”</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/NjnnoU8KWjA/</link>
		<comments>http://www.summa-tech.com/blog/2012/01/30/top-5-salesforce-spring-12-release-likes/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 15:41:31 +0000</pubDate>
		<dc:creator>Adam Menzies</dc:creator>
		
		<category><![CDATA[Cloud Applications]]></category>

		<category><![CDATA[chatter]]></category>

		<category><![CDATA[sales cloud]]></category>

		<category><![CDATA[salesforce]]></category>

		<category><![CDATA[service cloud]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=4207</guid>
		<description><![CDATA[Salesforce will officially put the <strong>Spring '12 release</strong> into the wild in early February. We've reviewed the official release notes in detail (get your own copy <a href="http://na9.salesforce.com/help/doc/en/salesforce_spring12_release_notes.pdf">here</a>).

As the release approaches we've hit the<img class="size-medium wp-image-4297 alignnone" style="border-style: initial; border-color: initial;" src="http://www.summa-tech.com/blog/wp-content/uploads/2012/01/facebook-like-button-300x133.jpg" alt="facebook-like-button" width="50" height="20" />button on <strong>five </strong>of the <strong>top features</strong>.  This list is written from a user and administrator perspective for people who both <strong>use </strong>and <strong>configure</strong> Salesforce systems on a daily basis. Be sure to add the features you're looking forward to most in the comments section. Enjoy and happy <strong>Spring '12</strong>!]]></description>
			<content:encoded><![CDATA[<p>Salesforce will officially put the <strong>Spring &#8216;12 release</strong> into the wild in early February. We&#8217;ve reviewed the official release notes in detail (get your own copy <a href="http://na9.salesforce.com/help/doc/en/salesforce_spring12_release_notes.pdf" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://na9.salesforce.com/help/doc/en/salesforce_spring12_release_notes.pdf');">here</a>).</p>
<p>As the release approaches we&#8217;ve hit the<img class="size-medium wp-image-4297 alignnone" style="border-style: initial; border-color: initial;" src="http://www.summa-tech.com/blog/wp-content/uploads/2012/01/facebook-like-button-300x133.jpg" alt="facebook-like-button" width="50" height="20" />button on <strong>five </strong>of the <strong>top features</strong>.  This list is written from a user and administrator perspective for people who both <strong>use </strong>and <strong>configure</strong> Salesforce systems on a daily basis. Be sure to add the features you&#8217;re looking forward to most in the comments section. Enjoy and happy <strong>Spring &#8216;12</strong>!</p>
<p><br\></p>
<h2>5. Chatter Messenger</h2>
<p>If your organization uses a chat client such as gchat, yahoo messenger, msn messenger, etc&#8230; for interoffice communication this feature will be of great interest to you. Chatter users will now be able to have <strong>live chats</strong> with each other using Chatter Messenger from within the Salesforce application. This could be used as another way to make Salesforce the go to application for your users, driving faster <strong>adoption </strong>across the organization. This feature will also be available to <strong>Chatter Plus</strong> and <strong>Chatter Free</strong> users, so truly anyone at your organization would be able to use this feature. It will be interesting to check this out with customer groups to see if chatting with customer Chatter users is also an option.</p>
<p>As you can see in the screenshot below, the interface is very similar to a popular social network we all love and/or hate:</p>
<p style="text-align: center;"><img class="size-medium wp-image-4208  aligncenter" src="http://www.summa-tech.com/blog/wp-content/uploads/2012/01/chatter_messenger-300x144.png" alt="Screen shot of Chatter Messenger in action" width="540" height="260" /></p>
<p>A few things to consider when implementing this feature:</p>
<ul>
<li>For Spring &#8216;12 this is being released as a <strong>Pilot Program</strong>, so you may need to contact Salesforce to have Chatter Messenger turned on</li>
<li>Chatter must be enabled for Chatter Messenger to be enabled</li>
<li>A user must <strong>follow </strong>another user to chat with them</li>
<li>Chatter Messenger can be disabled without disabling Chatter</li>
</ul>
<p style="text-align: center;"><span style="font-size: 20px;"><strong><br />
</strong></span></p>
<p><br\></p>
<h2>4. Case Feed</h2>
<p>In <strong>Service Cloud</strong> engagements in the past we&#8217;ve been asked to customize the Case entry, update and detail screens to maximize screen real estate and have had to replace these screens entirely with custom <strong>VisualForce</strong> screens that use APEX do AJAX updates. A number of those customizations will now be taken care of using the <strong>Case Feed </strong>feature in Spring &#8216;12.</p>
<p>This feature gives agents the ability to create, review and update Cases from a screen that gives them relevant Case details, Chatter feeds and also allows responses through multiple channels without navigating to another screen. The sidebar on this screen lets agents quickly switch between activities such as logging calls, Case notes, Case details as well as responding <strong>directly to the customer</strong>.</p>
<p>To use this feature Chatter must be enabled as well as Chatter tracking on Cases. For high-volume call centers that best utilize Chatter, this feature will be high impact and much easier to use and maintain than custom VisualForce solutions of the past.</p>
<div class="mceTemp mceIEcenter">
<dl>
<dt><img class="size-medium wp-image-4217 " src="http://www.summa-tech.com/blog/wp-content/uploads/2012/01/case_feed-300x172.png" alt="Case Feed Screenshot" width="450" height="258" /></dt>
</dl>
</div>
<p><br\></p>
<h2>3. Analytics Edition</h2>
<p>Analytics Edition brings the advanced, <strong>BI-like reporting</strong> so many have wanted from Salesforce for so long. This is an<strong> &#8220;Edition&#8221;</strong> feature which means you will need to add this edition to your org for an additional fee (available for Professional, Enterprise and Unlimited Editions). Contact your Salesforce rep for pricing <img src='http://www.summa-tech.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> The major new types of reports are:</p>
<ul>
<li><strong>Joined Reports:</strong> Create and run reports pulling data from multiple objects. (EX: Report on an Account&#8217;s Opportunities and Products associated with those Opportunities)</li>
<li><strong>Cross filters:</strong> Filter across multiple objects. ( EX:  Filter to see Cases from Organizations in a certain Region that also have Opportunities open that are greater than $100k)</li>
<li><strong>Bucketing:</strong> Segment your data on the fly without changing your data model. ( EX: report on open Opportunities by deal size, and group them into custom &#8220;Large&#8221;, &#8220;Medium&#8221; and &#8220;Small&#8221; groupings you create within the report.)</li>
</ul>
<p><br\></p>
<h2>2. Console Push Notifications</h2>
<p style="text-align: -webkit-auto;">A major concern our customers have raised is the issue of two agents or sales reps <strong>updating the same record simultaneously</strong>. This creates what in the programming world is called a &#8220;race condition&#8221; where the users are unknowingly in a race to get to the Save button <strong>last </strong>so that their changes are the changes ultimately saved on the record. This is especially a problem for <strong>high-volume call centers</strong>, both on Sales and Service Cloud. Now users will be able to see real-time push notification of field and record updates in the Salesforce Consoles.</p>
<p style="text-align: -webkit-auto;">As a user is viewing a queue or list view, or even updating a record on its detail screen, they will see changes being made by other users in <strong>real-time</strong>. Administrators can configure colors and bold text to be used to alert users of ongoing changes to a record, and the live notifications can be activated for the following objects (all fields):</p>
<ul>
<li>Custom Objects</li>
<li>Cases</li>
<li>Accounts</li>
<li>Contacts</li>
<li>Leads</li>
<li>Campaigns</li>
<li>Opportunities</li>
</ul>
<p><br\></p>
<h2>1. Schema Builder</h2>
<p>From an administrator or developer point of view, this is almost undoubtedly the most anticipated feature of Spring &#8216;12. Schema Builder has been available in a limited beta version that allowed users to read-only views of their org&#8217;s schema since Winter &#8216;12.</p>
<p>Schema Builder in Spring &#8216;12 (still in <strong>beta </strong>release, available in All Editions) can now be used to <strong>create custom objects, fields and relationships</strong> in an extremely fast manner. Custom objects can be created by dragging and dropping, fields and relationships created without the tedious clicking from screen to screen ways of the past. This feature should speed up creation of these objects, fields and relationships by an order of magnitude over the old way admins were forced to click from screen to screen.</p>
<p>Another advantage is the views of your database schema available to you to use for documentation, testing out new schema changes in the sandbox and to see the true data relationships that underlie your Salesforce instance.</p>
<p style="text-align: center;"><img class="aligncenter size-medium wp-image-4264" src="http://www.summa-tech.com/blog/wp-content/uploads/2012/01/schema_builder-300x236.png" alt="Schema Builder Screen Shot" width="450" height="354" /></p>
<p style="text-align: left;">
<p><span style="text-align: left;">The Schema Builder feature is probably best described through a demo, so I&#8217;ve included the following Spring &#8216;12 release preview below. Hit the 4:20 mark to go right to the Schema Builder demo. </span></p>
<p style="text-align: center;">
<object style="width:425px; height:344px;">
<param name="movie" value="http://www.youtube.com/v/hNsDUSmZlhg?version=3" />
<param name="allowScriptAccess" value="always" />
<param name="wmode" value="window" />
<embed src="http://www.youtube.com/v/hNsDUSmZlhg?version=3" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" wmode="window" width="425" height="344"></object>
</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/NjnnoU8KWjA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2012/01/30/top-5-salesforce-spring-12-release-likes/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2012/01/30/top-5-salesforce-spring-12-release-likes/</feedburner:origLink></item>
		<item>
		<title>Spring Batch - Imperfect Yet Worthwhile</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/55VW7vzUt_8/</link>
		<comments>http://www.summa-tech.com/blog/2012/01/23/spring-batch-imperfect-yet-worthwhile/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 15:13:36 +0000</pubDate>
		<dc:creator>Jeff Zapotoczny</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[batch processing]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Spring]]></category>

		<category><![CDATA[Spring Batch]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=4188</guid>
		<description><![CDATA[A lot of folks have used the <a href="http://www.springsource.org/" target="_blank">Spring framework</a> to build applications - and what's not to love? It's allowed us to solve enterprise problems with a minimum of tedium. And the framework has evolved to address criticisms, for example the continued reduction in need for lengthy XML configuration in application contexts in favor of ever more terse syntax and support for code annotations.

The framework as-packaged includes facilities to help with many common aspects of contemporary application development, from a Model-View-Controller (MVC) framework to  integration with persistence managers and elegant transaction management. But it doesn't necessarily cover every need. One example of a gap is batch processing.]]></description>
			<content:encoded><![CDATA[<p>A lot of folks have used the <a href="http://www.springsource.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.springsource.org/');" target="_blank">Spring framework</a> to build applications - and what&#8217;s not to love? It&#8217;s allowed us to solve enterprise problems with a minimum of tedium. And the framework has evolved to address criticisms, for example the continued reduction in need for lengthy XML configuration in application contexts in favor of ever more terse syntax and support for code annotations.</p>
<p>The framework as-packaged includes facilities to help with many common aspects of contemporary application development, from a Model-View-Controller (MVC) framework to  integration with persistence managers and elegant transaction management. But it doesn&#8217;t necessarily cover every need. One example of a gap is batch processing.</p>
<p>The idea behind batch processing is to allow a program to run without the need for human intervention - this may involve solving a problem that takes a lengthy amount of time, processing a large input set, or just automating some business process that doesn&#8217;t necessarily need to be triggered by a human. The batch paradigm was far more dominant in years past than it is in contemporary business computing, but that doesn&#8217;t mean valid batch use cases don&#8217;t continue to crop up. The operating system you&#8217;re using right now likely uses a batch approach to do all sorts of things for you without bugging you about it. Enjoying those automatic backups?</p>
<p>So what if you&#8217;ve got a problem that calls for a batch style solution but you&#8217;d still like to use Spring? On a recent project, we realized that much of the business logic we&#8217;d just finished writing within a web service framed with Spring could be reused for an upcoming batch component (which involved processing a potentially very large XML document that would be uploaded by a business partner). We briefly considered rolling a separate application that reused some of the same code, but before we went down that road someone mentioned hearing of &#8220;Spring Batch&#8221; - something that was not a part of Spring proper, but an auxiliary framework meant to complement it.</p>
<p>As you can read on its <a href="http://static.springsource.org/spring-batch/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://static.springsource.org/spring-batch/');" target="_blank">home page</a>,</p>
<blockquote><p>Spring Batch builds upon the productivity, POJO-based development  approach, and general ease of use capabilities people have come to know  from the Spring Framework, while making it easy for developers to access  and leverage more advanced enterprise services when necessary.</p></blockquote>
<p>Sounds great! So I dove in and started learning more about it. As I read the documentation, however, I have to admit I got a little overwhelmed by the complexity and amount of configuration needed for even a simple example. Unlike your average Spring application context, the context of a Spring  Batch application grows pretty quick and involves configuring a lot of  stuff that, at the outset, it just doesn&#8217;t seem like you should need to  configure. A &#8220;job repository&#8221; to track the status and history of job  executions, which itself <em>requires</em> a data source - just to get started? Wow, that&#8217;s a bit heavy handed. Worried that I might be misunderstanding what I&#8217;d found, I did some searching and found that <a href="http://www.cforcoding.com/2009/07/spring-batch-or-how-not-to-design-api.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.cforcoding.com/2009/07/spring-batch-or-how-not-to-design-api.html');" target="_blank">I wasn&#8217;t alone in thinking the API left something to be desired</a>.</p>
<p>But I&#8217;m not going to get as down on Spring Batch as the author of the article I just linked to. The reason being - once I determined what we <em>had </em>to configure in order to get a functional batch job running, I discussed the components involved with my team members and our client and we realized we would appreciate having all of those things. Logged history of batch runs in a database would be good, especially if there were ever a problem or failure. Then our client asked - will we have a UI to control it if we need to?</p>
<p>Enter <a href="http://static.springsource.org/spring-batch-admin/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://static.springsource.org/spring-batch-admin/');" target="_blank">Spring Batch Admin</a>. It&#8217;s unfortunate that the Admin capability is distributed separately from Spring Batch itself - because unless you hear about it or search with the right query, you might wind up rolling your own administrative UI unnecessarily. Of course you <em>can</em> write your own if you&#8217;d like - especially if you need to fit in with some pre-existing administrative app you may already have in place - but chances are you have better things to do and batch processing is just one portion of your project.</p>
<p>I&#8217;ve got a very important time-saving tip if you think you&#8217;d like to use the Admin UI, though: <em>decide if you need it first before starting to develop your batch capability</em>. I made the mistake of thinking it would be easier to get our batch capability working headlessly first, then bolt the Admin app onto the project, in an attempt to reduce complexity and break things down. Instead I wound up having to redo some of the POJOs and configuration involved in kicking off jobs to make what I&#8217;d done compatible with the Admin framework. In fact, starting with the Admin framework, and getting <em>it</em> up and running with its ability to run abstract jobs first, then customizing the jobs to meet your needs, would be the path of least resistance.</p>
<p>Once I had everything together, though, what a sweet capability this added up to! Using Spring Batch plus Spring Batch Admin gave my team a relatively low-overhead solution that allowed us to easily hand batch testing duties over to our client - all they had to know how to do was access a web page and click a button. Plus, we&#8217;ve given them a framework and a concrete example that is now easily repeatable - given a few POJOs and some copy/paste/modify of the application context XML, they could easily add new batch job types in the future.</p>
<p>That&#8217;s it for now - check back for a follow-up article in which I&#8217;ll dive into some example configurations and cover specific problems I encountered in my batch app and how I overcame them.</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/55VW7vzUt_8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2012/01/23/spring-batch-imperfect-yet-worthwhile/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2012/01/23/spring-batch-imperfect-yet-worthwhile/</feedburner:origLink></item>
		<item>
		<title>Usability Testing on Agile Projects (part 2)</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/n7tRYQhNQH0/</link>
		<comments>http://www.summa-tech.com/blog/2012/01/04/usability-testing-on-agile-projects-part-2/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 13:48:10 +0000</pubDate>
		<dc:creator>Ben Northrop</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[agile]]></category>

		<category><![CDATA[Scrum]]></category>

		<category><![CDATA[usability]]></category>

		<category><![CDATA[user interface]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3903</guid>
		<description><![CDATA[In <a href="http://www.summa-tech.com/blog/2011/11/20/usability-testing-on-agile-projects-part-1/">part 1</a> of this series, I discussed the benefits of usability testing on enterprise software projects and outlined a general approach for integrating the practice of usability testing into a typical Scrum project (see diagram below).  In this post, I'll lay out a 3-step process for performing a usability test on an enterprise project, and highlight how it can can hook into the standard elements of Scrum (e.g. <a href="http://www.mountaingoatsoftware.com/scrum/release-burndown">burndown</a>, <a href="http://www.mountaingoatsoftware.com/scrum/product-backlog">backlog</a>, etc.).  Here we go...]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.summa-tech.com/blog/2011/11/20/usability-testing-on-agile-projects-part-1/" >part 1</a> of this series, I discussed the benefits of usability testing on enterprise software projects and outlined a general approach for integrating the practice of usability testing into a typical Scrum project (see diagram below).  In this post, I&#8217;ll lay out a 3-step process for performing a <a href="http://en.wikipedia.org/wiki/Usability_testing" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Usability_testing');">usability test</a> on an enterprise project, describe some recognized best practices, and highlight how it can can hook into the standard elements of Scrum (e.g. <a href="http://www.mountaingoatsoftware.com/scrum/release-burndown" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.mountaingoatsoftware.com/scrum/release-burndown');">burndown</a>, <a href="http://www.mountaingoatsoftware.com/scrum/product-backlog" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.mountaingoatsoftware.com/scrum/product-backlog');">backlog</a>, etc.).  Here we go&#8230;</p>
<p><br/></p>
<div align="center">
<a href="http://www.summa-tech.com/blog/2011/11/20/usability-testing-on-agile-projects-part-1/scrum_and_usability_testing/"  rel="attachment wp-att-3874" target="_blank"><img src="http://www.summa-tech.com/blog/wp-content/uploads/2011/11/scrum_and_usability_testing-300x223.gif" alt="scrum_and_usability_testing" title="scrum_and_usability_testing" width="300" height="223" class="aligncenter size-medium wp-image-3874" /></a><br />
(<a href=http://www.summa-tech.com/blog/wp-content/uploads/2011/11/scrum_and_usability_testing.gif" rel="attachment wp-att-3874" target="_blank">click</a> to expand)
</div>
<h3>Step 1: Plan for the Test</h3>
<p>Preparation is the trickiest part of usability testing. If good users are not found, relevant tasks not defined, or environments not set-up, the results of the test will be specious at best, or non-existent at worst! It is crucial, therefore, to develop the right foundation for test: </p>
<p><b>Find the Users:</b> For the typical B2C web site, representative users can be found at any street corner or coffee shop. For many enterprise projects, however, users are not so easily located or accessed. Because users of enterprise software may have specific domain knowledge, work in different departments, or reside in different geographic offices, procuring access to them or aligning schedules can be a significant challenge. If possible, it is important to surmount these obstacles - real users will give <a href="http://www.useit.com/alertbox/20030120.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.useit.com/alertbox/20030120.html');">more accurate feedback</a>, and will be generally more receptive of the system when it is eventually rolled out, becoming advocates of it rather than opponents to it. </p>
<p>When it is not possible to find real users, representative users (e.g. mapping to defined <a href="http://www.agilemodeling.com/artifacts/personas.htm" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.agilemodeling.com/artifacts/personas.htm');">personas</a>), or even non-representative users, can be substituted with some success; many usability issues can be uncovered by users with no domain experience, a fresh set of eyes the most salient requirement. </p>
<p>It is <a href="http://www.useit.com/alertbox/20000319.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.useit.com/alertbox/20000319.html');">well documented</a> that usability testing requires no more than 4-6 users per round. Usability issues are typically universal and so are found early - there are diminishing returns for testing with any more than 6 users (i.e. they all tell you about the same problems!). </p>
<p><br/></p>
<div align="center">
<a href="http://www.summa-tech.com/blog/2012/01/04/usability-testing-on-agile-projects-part-2/users/"  rel="attachment wp-att-3904"><img src="http://www.summa-tech.com/blog/wp-content/uploads/2011/11/users-300x179.jpg" alt="users" title="users" width="300" height="179" class="aligncenter size-medium wp-image-3904" /></a></div>
<p><b>Plan the Tasks:</b> Not every feature of an application can or should be usability tested. As noted above, it is important, therefore, to identify for usability testing only those features which are prominent, complex, or have a high cost of user error. Once these features are identified, a script of user tasks can be created. Note that tasks should clear, concise, and worded in a way that is <a href="http://www.uie.com/articles/usability_testing_mistakes/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.uie.com/articles/usability_testing_mistakes/');">independent of the design</a> of the application (e.g. not &#8220;click &#8216;add item to cart&#8217; and click the &#8216;purchase&#8217; button&#8221; but rather &#8220;buy a widget&#8221;).  Lastly, it is important both to run through the script yourself, and also ask another team member to do the same, and ensure that the script takes no more than 15-30 minutes to execute (with the assumption that a user unfamiliar with the application could take 3x this long). </p>
<p><b>Write the Post-Test Questionnaire:</b> Depending on the application it may be useful to learn about not only the user&#8217;s performance (i.e. can they use the system) but also their preference (i.e. do they like it). Surprisingly, it has been found that the two <a href="http://www.usability.gov/methods/test_refine/learnusa/index.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.usability.gov/methods/test_refine/learnusa/index.html');">do not always correlate</a> - users may have problems using the application but say the like it, or use it fine but say they hate it. For this reason, it is important to supplement the observational data (i.e. notes from watching the user) with data from a post-test questionnaire. Note that demographic, qualitative, and quantitative data are important - so ask both open-ended questions like &#8220;how did you feel about XYZ?&#8221; and &#8220;on a scale of 1-5, was the system usable?&#8221;. Lastly, the late usability expert <a href="http://en.wikipedia.org/wiki/Randy_Pausch" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Randy_Pausch');">Randy Pausch</a> advocated always asking at least one question after a usability test: &#8220;what were the two worst things about the system?&#8221;, guaranteeing that the user will be forced to shed light on at least two tangible usability flaws (and not try to avoid hurting your feelings). </p>
<p><b>Set up the Environment, Data, and Access:</b> Finally, a stable and perhaps isolated version of the system must be available for the test participants to use. In many cases this will be the normal QA environment, but depending on the frequency of builds or transiency of the data, this may or may not be adequate. If it is not, alternatives may be either to deploy the system on your local machine or to create a special, temporary environment specifically for usability testing. The feasibility of these options obviously depends on the complexity of the application and dependent sub-systems, serivces, or data stores - a simple single web-app to single database may be easy to configure and deploy, whereas a complex system that leverages LDAP, multiple databases, an ERP, and a handful of external web-services would not be. </p>
<p>Additionally, for some usability test scripts, it will be necessary to have each user test with a fresh, pre-configured, non-confidential set of data (for example, maybe a user is asked to find the user with an outstanding balance, and so such a user must exist). If this is the case, a set of SQL set-up and tear-down scripts may be necessary, or perhaps just a script for manually re-creating the data via the user interface. In any case, it is imperative to understand the data dependencies for the test up-front, to ensure that tests go smoothly, and users find issues related to usability and not bad data conditions. </p>
<p>Lastly, in many cases the test subject will log in as a pre-configured, sample user, however in some cases it will be helpful for the user to log in as himself and see &#8220;his&#8221; data during the test. In this case, it is important to ensure the user has appropriate access control for the QA environment - and it&#8217;s not until he tries to log in that you discover that he doesn&#8217;t have authorization. </p>
<h3>Step 2: Perform the Test</h3>
<p>If planning is done correctly, actually performing the usability test should be a snap - your job is simply to make the subject feel comfortable, stand back, and watch what they do! Here are a few things to keep in mind. </p>
<p><b>Introduce Yourself and the Test:</b> When meeting the user, it&#8217;s important to set a very informal, relaxed, and open atmosphere early, so that the user feels comfortable sharing how they feel about the system. To that end, be sure to mention the following simple points: </p>
<ul>
<li>It is the system that is being tested, not them.</li>
<li>The system has issues, but it&#8217;s difficult for developers to see them because we are too close to the problem. This is why their help is so important.</li>
<li>Negative feedback is actually more helpful than positive. No feelings will be hurt if they are frustrated or don&#8217;t like something.</li>
<li>Their help is greatly appreciated, and will contribute to a better product.</li>
<li>If they get stuck you can jump in and help, but otherwise you&#8217;ll stay quiet and let them drive.</li>
</ul>
<p>After introductions, give them the test script and have them briefly skim the tasks. Convey to them that although the tasks should only take 30-45 minutes, they should feel comfortable taking their time. </p>
<p><b>Observe, Ask Questions, but Don&#8217;t Help:</b> Once the user has begun, it&#8217;s important to let them use the system as they wish, even if it means them navigating down false paths (the whole point is to see how they would use it if you weren&#8217;t there!). As they complete the tasks, <a href="http://en.wikipedia.org/wiki/Think_aloud_protocol" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Think_aloud_protocol');">encourage them to talk</a>, and be sure to ask probing, but non-revealing, questions, like &#8220;I saw that you clicked the &#8216;filter&#8217; button but were surprised with the result - what did you expect would happen there?&#8221;. If the user is hopelessly stuck, then it may be necessary to give them hints, but otherwise remain an observer.</p>
<p><b>Take Notes:</b> As the user completes the tasks, take copious notes of their actions, comments, and frustrations - these notes will trigger your memory later and fuel the <i>Usability Observations</i> list that you assemble. Many would <a href="http://www.boxesandarrows.com/view/recording_screen_activity_during_usability_testing" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.boxesandarrows.com/view/recording_screen_activity_during_usability_testing');">argue</a> that it is necessary to also video record usability test sessions, however, the benefit is rarely worth the cost in my opionion (even though it is relatively <a href="http://camstudio.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://camstudio.org/');">cheap</a>): project stakeholders seldom take the time to actually view a usability test video session, users may be apprehensive and less honest when being recorded, and the set-up and storage of the recordings can be frustrating and time-consuming.</p>
<h3>Step 3: Analyze the Results</h3>
<p>Once the tests have been completed, the data must be analyzed and then synthesized into a set of actionable recommendations. To do so, two artifacts can be created, an objective <i>Usability Observations List</i> and a subjective <i>Usability Analysis &#038; Recommendation</i> document.</p>
<p><b>Create a Usability Observations list:</b> Go back through your notes, and record discrete usability issues that users encountered in a simple spreadsheet. The list should be objectively and tactfully worded, stating, for example, that the user &#8220;did not know what the word &#8216;invoice&#8217; meant&#8221; and not &#8220;&#8216;invoices&#8217; should be called &#8216;bills&#8217;&#8221;. Consensus should be noted for each item (e.g. &#8220;3 out 6 users&#8221;), and each should be classified either as a &#8220;usability bug&#8221; (which would later be entered in an issue tracking system to be implemented during the current sprint) or as a &#8220;feature request&#8221; (which would be added to the product backlog, to be prioritized for a future sprint). </p>
<p><b>Create a Usability Analysis &#038; Recommendation document:</b> Finally, it will be helpful for project stakeholders to receive a high-level analysis of the usability test, summing up overall impression of the site&#8217;s usability (using both quantitative and qualitative data as useful), the areas of the system that were most and least usable, and a set of recommendations for future action (e.g. new features to the backlog, additional rounds of usability testing, etc.). This document may captured in a Wiki, stored in document control (e.g. SharePoint), or just sent via email. </p>
<p>That&#8217;s it!  Again, I&#8217;d like to hear your thoughts on usability testing on enterprise projects.  Please share!</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/n7tRYQhNQH0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2012/01/04/usability-testing-on-agile-projects-part-2/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2012/01/04/usability-testing-on-agile-projects-part-2/</feedburner:origLink></item>
		<item>
		<title>“My Scrum Master is in a different time zone.  Can this ever work?” or 4 Tips To Making Agile Work With A Distributed Team</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/TmrIjpaRQBc/</link>
		<comments>http://www.summa-tech.com/blog/2011/12/19/%e2%80%9cmy-scrum-master-is-in-a-different-time-zone-can-this-ever-work%e2%80%9d-or-4-tips-to-making-agile-work-with-a-distributed-team/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 18:53:50 +0000</pubDate>
		<dc:creator>Adrian Wright</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[agile]]></category>

		<category><![CDATA[collaboration]]></category>

		<category><![CDATA[Rally]]></category>

		<category><![CDATA[Scrum]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3826</guid>
		<description><![CDATA[Agile software development is about team code ownership, collaboration, and sharing ideas to <strong>get stuff done</strong>.  You want to ride the Agile wave, but half your team is in one city and the rest are in another.  How can you get your guys and gals to collaborate over the wire?  Recently I've been working on a project like this and I've found a few things that can make your team efficient, collaborative, and successful in an Agile environment.
]]></description>
			<content:encoded><![CDATA[<p>Agile software development is about team code ownership, collaboration, and sharing ideas to <strong>get stuff done</strong>.  You want to ride the Agile wave, but half your team is in one city and the rest are in another.  How can you get your guys and gals to collaborate over the wire?  Recently I&#8217;ve been working on a project like this and I&#8217;ve found a few things that can make your team efficient, collaborative, and successful in an Agile environment.</p>
<h2>Take Down Your Task Board</h2>
<p>If you really believe in eliminating waste, and your team is not co-located, the scrum board in your war room is nothing but waste.  The original purpose was for information to be accessible to the team.  You should be able to look at it and know immediately what your comrades are up to.  If you are co-located, you&#8217;d have to ask someone to <strong>go update the board for you</strong>.  That slows both of you down, which isn&#8217;t so lean.  This leads me to my next point.</p>
<h2>Invest in an online storyboard and make it your homepage</h2>
<p>There are a lot of good ones out there.  I prefer <a title="Rally" href="http://www.rallydev.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.rallydev.com/');">Rally</a> (shameless plug for <a title="our new partner" href="http://www.summa-tech.com/partners/" >our new partner</a>).  It gives us all the basics &#8212; stories, defects, test cases, a burndown chart, as well as a lot of really helpful plugins.</p>
<p>I know what you&#8217;re thinking &#8212; this is starting to feel like the old project management style.  What&#8217;s to keep Rally from becoming the new rigid project plan?  Like any tool, it can be abused, but consider the benefits:</p>
<ul>
<li>One story board for everyone to see, even if they&#8217;re in your Maui office.</li>
<li>Team views that show you what your teammates are working on, so you can offer to help if someone is falling behind</li>
<li>Sprint burndown and velocities to help you plan for the future</li>
</ul>
<p>And heck, if you&#8217;re only happy with a story board on the wall, you could adapt <a title="what these guys are doing" href="http://www.targetprocess.com/blog/2011/07/visual-builds-board.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.targetprocess.com/blog/2011/07/visual-builds-board.html');">what these guys are doing</a>.</p>
<h2>Invest in collaboration software</h2>
<p>So we&#8217;ve got iteration tracking covered; how do we collaborate?  We&#8217;ve all been there when the guy you need to look at your broken code is working from home or sits at the other office.  Checking in questionable code is never a good idea, and you may be using centralized source control so you can&#8217;t use the wonders of <a title="Git" href="http://git-scm.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://git-scm.com/');" target="_blank">Git</a> and <a title="Mercurial" href="http://mercurial.selenic.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://mercurial.selenic.com/');" target="_blank">Mercurial</a> to let your buddy pull in your changes and show you where you you went wrong with your NHibernate cascade.</p>
<p>Every distributed team needs, at a minimum:</p>
<ul>
<li>Screen sharing software &#8212; <a title="Webex" href="http://www.webex.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.webex.com');">Webex</a>, <a title="Join.Me" href="https://join.me/" onclick="javascript:pageTracker._trackPageview('/outbound/article/https://join.me/');">Join.Me</a>, <a title="Skype" href="http://www.skype.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.skype.com');">Skype</a>, take your pick.  You need to be able to share your screen so you can see what&#8217;s going on.  Encourage pair programming over the wire to get people comfortable with the tool and getting to know each other&#8217;s style.</li>
<li>Chat software (no investment there) &#8212; It&#8217;s quick, easy, simple, and most of all, quiet.  Nothing disturbs the development room more than a noisy phone conversation.</li>
<li>Reliable internet access &#8212; It seems obvious, make sure all your guys have a strong connection.  Nothing slows collaboration down more than a code review Webex that keeps flaking out.</li>
<li>Phone conferencing lines available to anyone, at the ready.  There are even some free ones out there &#8212; my team has used <a title="FreeConferenceCall" href="http://www.freeconferencecall.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.freeconferencecall.com');">FreeConferenceCall</a> with a lot of success.</li>
</ul>
<h2>Stick to the Agile Basics</h2>
<p>If your team sticks to the <a title="agile basics" href="http://agilemanifesto.org" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://agilemanifesto.org');">agile basics</a>, they are 90% of the way there to a strong development experience, even if they aren&#8217;t co-located.  A few things to remember:</p>
<ul>
<li>The team owns the code &#8212; collaborate and work together to find the best solution.</li>
<li>Communicate progress and blocks &#8212; no one benefits if you don&#8217;t ask for help when you&#8217;re stumped, when you don&#8217;t want to be pushy about a block, or when you hide progress for fear of being assigned more work.  Communicate more and you&#8217;ll do more.  Just don&#8217;t communicate so much that no one else gets anything done&#8230;  :)</li>
<li>Eliminate waste and ask questions about process &#8212; if you think something doesn&#8217;t have much benefit, speak up.  Maybe you&#8217;re right, or maybe you&#8217;ll learn something in the process.  Many of you are familiar with <a title="Seth Godin's TED Talk" href="http://www.ted.com/talks/seth_godin_this_is_broken_1.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.ted.com/talks/seth_godin_this_is_broken_1.html');">Seth Godin&#8217;s TED talk</a> on this subject.  If you aren&#8217;t, go watch it.  You&#8217;ll like it.</li>
</ul>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/TmrIjpaRQBc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/12/19/%e2%80%9cmy-scrum-master-is-in-a-different-time-zone-can-this-ever-work%e2%80%9d-or-4-tips-to-making-agile-work-with-a-distributed-team/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/12/19/%e2%80%9cmy-scrum-master-is-in-a-different-time-zone-can-this-ever-work%e2%80%9d-or-4-tips-to-making-agile-work-with-a-distributed-team/</feedburner:origLink></item>
		<item>
		<title>12 Days of a Consultant’s Christmas!</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/QpFbF9Skkrs/</link>
		<comments>http://www.summa-tech.com/blog/2011/12/12/12-days-of-a-consultant%e2%80%99s-christmas/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 20:51:46 +0000</pubDate>
		<dc:creator>Zack Mance</dc:creator>
		
		<category><![CDATA[Process Integration]]></category>

		<category><![CDATA[Summa]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=4038</guid>
		<description><![CDATA[The Holidays are here! Soon snow will be falling, presents will be wrapped, and kids will be in line for Santa at the mall. I thought to myself, in this stressful/wonderful time of the year I would write a little light reading for the blog! I know that sometimes technical blogging can be a little on the strenuous side, so sit back, relax, and hum the tune with me! I know that you know it!]]></description>
			<content:encoded><![CDATA[<div class="seriesmeta">This entry is part 8 of 8 in the series <a href="http://www.summa-tech.com/blog/series/saas-integration/"  title="series-188">SaaS Integration</a></div><p>The Holidays are here! Soon snow will be falling, presents will be wrapped, and kids will be in line for Santa at the mall. I thought to myself, in this stressful/wonderful time of the year I would write a little light reading for the blog! I know that sometimes technical blogging can be a little on the strenuous side, so sit back, relax, and hum the tune with me! I know that you know it!</p>
<h3>On the first day of Christmas the consultants gave to me, an Agile Project Using, Rally!</h3>
<p>On September 26th 2011, Summa announced that it was now a partner with Rally Software! Rally, current leader in Agile application lifecycle management. Recognized Summa’s ability to provide solutions and services that help development teams adopt Agile methodologies. Therefore Summa is now considered a Rally Enablement Partner! See the full article <a href="http://www.summa-tech.com/news/summarallypartnership-pr.php4" >here</a>.</p>
<h3>On the second day of Christmas the consultants gave to me, two PTC Awards…</h3>
<p><em>and an Agile Project using, Rally</em></p>
<p>This year Summa was nominated for two Pittsburgh Technical Council Awards. The first of which was for Technology Accelerator of the Year! The Second of which was for a video that we created that explained why we should win this award. The Video titled “Summa Dogs” can be viewed <a href="http://www.youtube.com/watch?v=7EnSrb916HA&amp;feature=youtu.be" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.youtube.com/watch?v=7EnSrb916HA&amp;feature=youtu.be');">here</a>!</p>
<h3>On the third day of Christmas the consultants gave to me, three UI Designs…</h3>
<p><em>Two PTC Awards and an Agile Project using Rally!</em></p>
<p>It has been a busy year for us here at Summa! Along with all of the other things going on, we announced on November 8th, 2011 that we had acquired LotterShelly. LotterShelly is a strategic design consultancy that has partnered with Summa on several of our projects. Delivering high end prototypes, designing user interfaces for complex software-intensive products. Our acquisition will provide Summa with the vital component of User Experience Design and will allow them to deliver new value to our customers. See the full article <a href="http://www.summa-tech.com/news/summalottershellyacquisition-pr.php4" >here</a>!</p>
<h3>On the fourth day of Christmas the consultants gave to me, four Healthcare Solutions…</h3>
<p><em>Three UI Designs, Two PTC Awards, and an Agile Project using Rally!</em></p>
<p>On November, 19th 2011 IBM announced that Summa was one of nine Business Partners to achieve IBM Software Value Plus Industry Authorization. We were selected for our focus and track record in the Healthcare Industry. Our Healthcare Solutions Practice allows us to concentrate on systems interoperability, clinical and administrative workflow, user experience, data management and middleware implementation. Read the entire Press Release <a href="http://www.summa-tech.com/news/ibmindustryauthorization-pr.php4" >here</a></p>
<h3>On the fifth day of Christmas the consultants gave to me, five Closed Bells Ringing…</h3>
<p><em>Four Healthcare Solutions, Three UI Designs, Two PTC Awards, and an Agile Project using Rally!</em> </p>
<p>Ah the sound of bells around the Holidays. It always makes me think of The Grinch who Stole Christmas! Around the Summa office it is a well known fact that when you hear a bell (there is a real bell outside of one of our offices) that we have successfully gained a new engagement! Sometimes we just #Ring on SalesForce Chatter too, but that is not nearly as fun! If Summa’s consultants can get 5 rings this season it would put a smile on all our faces!</p>
<h3>On the sixth day of Christmas the consultants gave to me, six CRM Solutions…</h3>
<p><em>Five Closed Bells Ringing, Four Healthcare Solutions, Three UI Designs, Two PTC Awards, and an Agile Project using Rally!</em></p>
<p>With last year’s acquisition of HarvestGold, Summa can now offer Salesforce.com solutions to over 150 customers! We have a wide range from start-up complaints to large enterprise corporations across many industries! In our 10+ years of application development and integration expertise coupled with a long-time partnership with Salesforce.com, we have a long list of satisfied customers who continue to work with us! Learn more about our CRM Solutions <a href="http://www.summa-tech.com/solutions/crm/" >here</a>!<</p>
<h3>On the seventh day of Christmas the consultants gave to me, seven Summanoids-a-blogging…</h3>
<p><em>Six CRM Solutions, Five Closed Bells Ringing, Four Healthcare Solutions, Three UI Designs, Two PTC Awards, and an Agile Project using Rally!</em></p>
<p>So if you are reading this you are already well aware of the Summa Blog. Now let me ask if you are aware of all the areas of the blog! Summa has several categories that you can choose from. If you are interested in Agile and Development, to Cloud Applications, maybe it is just some Summa related topics, or you can venture into the great unknown with Uncategorized! Each area, and blogger have their own style and topics they enjoy writing about. So kick back, relax, and take in some light reading! Check out the <a href="http://www.summa-tech.com/blog/" >Summa blog home page</a>!</p>
<h3>On the eighth day of Christmas the consultants gave to me, eight Teams-a-Scrumming…</h3>
<p><em>Seven Summanoids-a-blogging, Six CRM Solutions, Five Closed Bells Ringing, Four Healthcare Solutions, Three UI Designs, Two PTC Awards, and an Agile Project using Rally!</em></p>
<p>I know that Scrum sounds like some sort of rugby term, and it still is. It is also a project management style used in Agile Software development. It is an iterative, incremental framework that Summa utilizes in a large number of our projects. It would take me an entire blog post to write about all the ins and outs of Scrum, and maybe someday I will! Summa has had a large amount of success using Scrum. To add to the power of the Scrum, Summa is now partnered with Rally. Using the right Agile tools, with the right Agile methodology can be a formula for continued successes!</p>
<h3>On the ninth day of Christmas the consultants gave to me, nine Client Partners…</h3>
<p><em>Eight Teams-a-Scrumming, Seven Summanoids-a-blogging, Six CRM Solutions, Five Closed Bells Ringing, Four Healthcare Solutions, Three UI Designs, Two PTC Awards, and an Agile Project using Rally!</em></p>
<p>Summa provides a large range of comprehensive solutions for our customers! To provide these solutions we partner with leading technology companions and complementary service providers!</p>
<ul>
<li>IBM Corporation</li>
<li>Cast Iron Systems</li>
<li>Salesforce.com</li>
<li>Microsoft Corporation</li>
<li>Rally</li>
<li>Rockwell Automation</li>
<li>Java.net</li>
<li>Summa Brazil</li>
<li>TheNavigatorGroup</li>
</ul>
<p>For full details about the partnership between Summa and these companies check out more information <a href="http://www.summa-tech.com/partners/" >here</a>!</p>
<h3>On the tenth day of Christmas the consultants gave to me, ten Team Members-a-leading…</h3>
<p><em>Nine Client Partners, Eight Teams-a-Scrumming, Seven Summanoids-a-blogging, Six CRM Solutions, Five Closed Bells Ringing, Four Healthcare Solutions, Three UI Designs, Two PTC Awards, and an Agile Project using Rally!</em></p>
<p>A corner stone to the Success of Summa has always been its leadership team! Each one plays a key role in our long term goals, strategic planning, and day to day lives! The following is a list of our leadership team, for full bios on each check it out on our website <a href="http://www.summa-tech.com/about/management/" >here</a>!</p>
<ul>
<li>Edward Engler :: Chairman and Founder</li>
<li>Audrey Dunning :: Chief Executive Officer</li>
<li>Pedro Barelli :: Chief Operating Officer</li>
<li>Rick Kotermanski :: Chief Technology Officer</li>
<li>Dan McDermott :: Chief Delivery Officer</li>
<li>Jeremy Smith :: Practice Manager, Healthcare Solutions</li>
<li>Jason Armstrong :: Practice Director, Business Transformation Solutions</li>
<li>Mike Ripple :: VP of CRM Solutions</li>
<li>Steve Lippock :: VP, CRM Sales and Business Development</li>
<li>Betty George :: Director of Business Development</li>
</ul>
<h3>On the eleventh day of Christmas the consultants gave to me, eleven Performance Solutions…</h3>
<p><em>Ten Team Members-a-Leading, Nine Client Partners, Eight Teams-a-Scrumming, Seven Summanoids-a-blogging, Six CRM Solutions, Five Closed Bells Ringing, Four Healthcare Solutions, Three UI Designs, Two PTC Awards, and an Agile Project using Rally!</em></p>
<p>Users expect more from applications today then they have ever done before. Speed, reliability, and usability are all things in today’s world that are a must. Summa provides the expertise to help clients improve performance without just throwing hardware at the problem.  Application performance engineering is a possibility that is often over looked, but shouldn’t be.  We will lay out a comprehensive road map for the client starting with a baseline performance reading, a report on where issue resides (network or application-related), and outline a plan for addressing the issue. From there the client can decide on what route they want to take. Don’t get left stuck in the mud, check out the entire write-up on our <a href="http://www.summa-tech.com/solutions/performance/" >Performance Solutions</a>!</p>
<h3>On the twelfth day of Christmas the consultants gave to me, twelve Applications Modernizing…</h3>
<p><em>Eleven Performance Solutions, Ten Team Members-a-Leading, Nine Client Partners, Eight Teams-a-Scrumming, Seven Summanoids-a-blogging, Six CRM Solutions, Five Closed Bells Ringing, Four Healthcare Solutions, Three UI Designs, Two PTC Awards, and an Agile Project using Rally!</em></p>
<p>So we have come to the end of the road…. And I can’t … wait wrong song! Let’s get back on track. Application Modernization, nine syllables that can change the way your business or product can be preserved.  In the fast paced world of technology a state of the art application five years ago can be obsolete tomorrow. Summa understands this, and knows that clients sometimes need help keeping their applications up-to-date. We are here to help you take advantage of the latest technology advances. It is hard to find a cost-effective solution that takes into account all the variables that a company has to deal with. With 15 years of experience Summa has a niche for helping clients find the right solution(s) that fit their needs! Check out the full summary <a href="http://www.summa-tech.com/solutions/update/" >here</a>!</p>
<p>Happy Holidays!<br />
&#8211;Zack</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/QpFbF9Skkrs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/12/12/12-days-of-a-consultant%e2%80%99s-christmas/feed/</wfw:commentRss>
	
		<series:name><![CDATA[SaaS Integration]]></series:name>
	<feedburner:origLink>http://www.summa-tech.com/blog/2011/12/12/12-days-of-a-consultant%e2%80%99s-christmas/</feedburner:origLink></item>
		<item>
		<title>Four Java Surprises!</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/YbRHb_wrCkI/</link>
		<comments>http://www.summa-tech.com/blog/2011/12/05/four-java-surprises/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 15:06:51 +0000</pubDate>
		<dc:creator>Prem Nagrath</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[generics]]></category>

		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=4027</guid>
		<description><![CDATA[Here are four things in Java that might surprise you:

Polymorphism doesn't work the way you might expect.  For example, consider <a href="http://http://en.wikipedia.org/wiki/Subtype_polymorphism" target="_self">subtype polymorphism</a> with <a href="http://http://en.wikipedia.org/wiki/Generics_in_Java" target="_self">Generics</a>. To elaborate, even though B is a subtype of A, and it is perfectly valid to say:]]></description>
			<content:encoded><![CDATA[<p>Here are four things in Java that might surprise you:</p>
<h3>1. Polymorphism and Generics</h3>
<p>Polymorphism doesn&#8217;t work the way you might expect with <a href="http://http://en.wikipedia.org/wiki/Generics_in_Java" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://http://en.wikipedia.org/wiki/Generics_in_Java');" target="_self">generics</a>.  For example, consider <a href="http://http://en.wikipedia.org/wiki/Subtype_polymorphism" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://http://en.wikipedia.org/wiki/Subtype_polymorphism');" target="_self">subtype polymorphism</a>. Even though B is a subtype of A, and it is perfectly valid to say:</p>
<pre name="code" class="java:nocontrols:nogutter">
A a = new B();
</pre>
<p>&#8230;the following, however, would give a compiler error:</p>
<pre name="code" class="java:nocontrols:nogutter">
List&lt;A&gt; aListOfA = new ArrayList&lt;B&gt;();
</pre>
<p>The reason is that a List of B is not considered a subtype of List of A, even though B is a subtype of A. So how do we declare a collection that can store subtypes of a given class? Here it is:</p>
<pre name="code" class="java:nocontrols:nogutter">
Collection&lt;? extends A&gt;  aListOfA;
</pre>
<p>This says that aListOfA holds elements of an &#8220;unknown&#8221; subtype of A. Now, it is perfectly valid to assign a List of B to aListOfA, for example:</p>
<pre name="code" class="java:nocontrols:nogutter">
List&lt;B&gt; aListOfB =  new ArrayList&lt;B&gt;();
aListOfA  = aListOfB ;
</pre>
<p>Of course, you can only retrieve elements from aListOfA, and expect them to be of type A. Adding an element to this List would still give you a compiler error though.  This is a downside of using <a href="http://www.java2s.com/Tutorial/Java/0200__Generics/BoundedWildcards.htm" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.java2s.com/Tutorial/Java/0200__Generics/BoundedWildcards.htm');">bounded widlcards</a>.</p>
<h3>2. BigDecimal and primative doubles</h3>
<p>Most of us would agree that the <a href="http://docs.oracle.com/javase/6/docs/api/java/math/BigDecimal.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://docs.oracle.com/javase/6/docs/api/java/math/BigDecimal.html');" target="_self">BigDecimal </a>class is probably one of the best classes to use when performing financial calculations. A word of caution here is to not use the constructor of BigDecimal that takes the primative double as a parameter. The reason is that the result from this constructor is unpredictable, especially for values involving decimals (remember that Java, or any programming language for that matter, <a href="http://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency');">cannot store the decimal fractions exactly</a> when using a double and a float). The other constructor that takes a String is generally recommended and performs much better.</p>
<p>Also, note that equals method in BigDecimal compares not only the value of the two objects, it also compares the scale, and returns true only if both are equal.</p>
<h3>3. StringBuffer and the equals() method</h3>
<p>You might assume that the equals() method is overridden in the StringBuffer (just like the String class), because IT IS NOT!  <a href="http://http://docs.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://http://docs.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html');" target="_self">StringBuffer </a>does not behave like <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/String.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://docs.oracle.com/javase/6/docs/api/java/lang/String.html');" target="_self">String </a>when it comes to &#8220;equality&#8221;.  For example, if you run the following code, you will get false for the first S.O.P and true for the second S.O.P.</p>
<pre name="code" class="java:nocontrols">
public class Test{
  public static void main(String[] args) {
    StringBuffer aStringBuffer = new StringBuffer("StringBuffer");
    StringBuffer anotherStringBuffer = new StringBuffer("StringBuffer");
    System.out.println(aStringBuffer.equals(anotherStringBuffer));
    System.out.println(aStringBuffer.toString().equals(anotherStringBuffer.toString()));
  }
}
</pre>
<p>This is not very intuitive, but there is an explanation (<a href="http://www.coderanch.com/t/410563/java/java/Why-Stringbuffer-not-implemented-equals" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.coderanch.com/t/410563/java/java/Why-Stringbuffer-not-implemented-equals');">here</a> and <a href="http://www.velocityreviews.com/forums/t367753-how-equals-method-works-in-stringbuffer.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.velocityreviews.com/forums/t367753-how-equals-method-works-in-stringbuffer.html');">here</a>).</p>
<h3>4. Object heap size and OutOfMemoryError</h3>
<p>Generally, the first thing that we do when we see an <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/OutOfMemoryError.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://docs.oracle.com/javase/6/docs/api/java/lang/OutOfMemoryError.html');" target="_self">OutOfMemoryError</a> is increase the Object heap size using &#8220;-Xmx/-Xms&#8221; options on JVM. In most cases it should (and it does!) fix the problem but don’t be surprised if you continue to see this error. Here is the explanation:</p>
<p>JVM needs memory not just for the object heap, the place where objects are stored, but also for storing classes and other metadata. This space in memory is called Permanent Space and when JVM runs out of this space, a familiar <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/OutOfMemoryError.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://docs.oracle.com/javase/6/docs/api/java/lang/OutOfMemoryError.html');" target="_self">OutOfMEmoryError</a> is thrown which needs to be fixed differently. So how do we differentiate between the two errors, one that occurs when Object heap runs out of memory and the other one when Permanent space runs out of memory? In the case of the former you will see something like &#8220;java.lang.OutOfMemoryError: Java heap space&#8221; and for the latter one you will see something like &#8220;java.lang.OutOfMemoryError: PermGen space&#8221;. You can fix the object heap problem by increasing the heap size, but doing the same would not help in fixing the Permanent Space error. In fact, it might make the problem worse as an increase in object heap size would result in even less memory available for Permanent Space. Use &#8220;-XX:PermSize&#8221; to set the new initial permanent space size and &#8220;-XX:MaxPermSize&#8221; to set the new max permanent space size instead.</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/YbRHb_wrCkI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/12/05/four-java-surprises/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/12/05/four-java-surprises/</feedburner:origLink></item>
		<item>
		<title>The Power of Functional Thinking:  An Ode in f(n) parts</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/8Rjv13k0ZfI/</link>
		<comments>http://www.summa-tech.com/blog/2011/11/28/the-power-of-functional-thinking-an-ode-in-fn-parts/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 14:27:47 +0000</pubDate>
		<dc:creator>Steve Ayers</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[functional programming]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3850</guid>
		<description><![CDATA[There is an episode of the sitcom Friends where Joey is approached by a travelling encyclopedia salesman, offering to peddle him the entire collection of his wares, the complete Encyclopedia  Britannica.  Being a struggling actor and lacking the money, Joey opts to simply buy a single volume of the collection:  the book focusing on the letter V.  Joey, thinking back, realizes that there are many instances throughout his life where he sits dumbfounded as the other friends carry on conversations on subjects about which Joey has no knowledge.  So, instead, he nods convincingly, pretending he understands.  This V volume will allow him to participate intelligently, he thinks.  However, much to his dismay, the first time he gets to exhibit his new knowledge, the conversation swings from a proposed topic of Joey's (Vietnam) to something related, but starting with another letter:  the Korean War.  Since Joey doesn't own the K volume, he again has to sit there, crestfallen, while the conversation carries on without him.

Admittedly, functional programming has been my K volume.  I spent years learning the ins and outs of object-oriented programming, stammering through explanations of polymorphism and encapsulation, regurgitating the <a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612">Gang of Four design patterns</a> whenever applicable.  I was ready, I thought.  When that conversation eventually started in Central Perk, I was going to be prepared.  But, just when I thought I knew all there was to know, everyone went and shifted the damn letter on me.]]></description>
			<content:encoded><![CDATA[<h3>Part I:  My K Volume</h3>
<p>There is an episode of the sitcom Friends where Joey is approached by a travelling encyclopedia salesman, offering to peddle him the entire collection of his wares, the complete Encyclopedia  Britannica.  Being a struggling actor and lacking the money, Joey opts to simply buy a single volume of the collection:  the book focusing on the letter V.  Joey, thinking back, realizes that there are many instances throughout his life where he sits dumbfounded as the other friends carry on conversations on subjects about which Joey has no knowledge.  So, instead, he nods convincingly, pretending he understands.  This V volume will allow him to participate intelligently, he thinks.  However, much to his dismay, the first time he gets to exhibit his new knowledge, the conversation swings from a proposed topic of Joey&#8217;s (Vietnam) to something related, but starting with another letter:  the Korean War.  Since Joey doesn&#8217;t own the K volume, he again has to sit there, crestfallen, while the conversation carries on without him.</p>
<p>Admittedly, functional programming has been my K volume.  I spent years learning the ins and outs of object-oriented programming, stammering through explanations of polymorphism and encapsulation, regurgitating the <a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612');">Gang of Four design patterns</a> whenever applicable.  I was ready, I thought.  When that conversation eventually started in Central Perk, I was going to be prepared.  But, just when I thought I knew all there was to know, everyone went and shifted the damn letter on me.</p>
<p>Now, instead of people talking about Vietnam and Object Oriented Programming, they were discussing Korea and Functional Programming.  So, I set about to learn what this new approach was (turns out its not a new approach at all) and just what made it so important.</p>
<p>When I first heard about aspect-oriented programming, the one thing that was stressed in all the descriptions was that &#8216;this is NOT a replacement for object-oriented programming&#8217;.  AOP was merely meant as a complement to it.  It is something to assist you in easily developing logic that covers the crosscutting concerns you shouldn&#8217;t have to worry about in an application.  It was basically seasoning for the tried-and-true approach of OOP.</p>
<p>But, if AOP is a seasoning, then Functional Programming is a totally different entrée in a new restaurant.  It is a paradigm shift.  Functional Programming IS a replacement for OOP.  Where OOP focuses on objects and the encapsulation of concerns and behavior, functional programming focuses instead on the actions done to those objects.  Where OOP seeks to make it easier to add more nouns to your application, functional programming seeks to make it easier to add more verbs.  Where OOP focuses on changes in state, functional programming focuses on changes in actions.</p>
<p>But, what really attracted me to functional programming was its elegant conciseness.  I admire its focus on purity, eliminating the verbose, and the mathematical roots from which it proudly inherits.</p>
<p>Functional programming derives its name from the notion of functions in mathematics.  Because of its focus on immutability, it can guarantee side-effect free calculation.  You pass in arguments to a function, you are returned a result and nothing has changed in the process.  This allows for great reuse across many scenarios since external dependencies and state remain consistent.</p>
<p>But its more than that.  There are certain tenets that make functional programming unique.  The list of items are what make it not just another entree, but a minimalist delicacy that could replace the nine-course Roman orgies you&#8217;re used to consuming.</p>
<p>So, in an effort to clarify this for those of you who, like me at one point, are wondering what the fuss is all about, look no further.  We&#8217;ll get through this together.  Following is the dogma of functional programming:</p>
<h4>Immutability</h4>
<p>The first thing that concurrency experts preach is immutability.  If your state cannot change, then thread-safety is not an issue.  The problem with this is that immutability in Java is HARD to accomplish.  Its not a natural thing.  It takes time and preparation.</p>
<p>In functional programming languages immutability is the status quo.  In languages such as <a href="http://clojure.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://clojure.org/');">Clojure</a>, EVERYTHING is immutable except the references to objects, which allows you to maintain a history of changes over time.  When you can operate on the base assumption that state is immutable, there are certain leaps of faith that are easy to take.</p>
<p>For example, take the following tree.  It is possible to completely change the structure of tree by simply pointing a new reference to different left and right nodes.  This is through sharing of certain elements that are not changing.  This would not be possible if the elements were mutable because changing a shared element would affect all structures everywhere the element was shared.</p>
<p><img class="aligncenter size-medium wp-image-3943" src="http://www.summa-tech.com/blog/wp-content/uploads/2011/11/persistentdatastructures1-300x134.png" alt="persistentdatastructures1" width="450" height="201" /></p>
<h4>High Order Functions (Closures)</h4>
<p>Closures are the buzzword of the minute.  Everyone is throwing them around, but not because they’re the latest and greatest feature.   Javascript has had them for years and Scheme first implemented them in when <a href="http://en.wikipedia.org/wiki/Steely_Dan" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Steely_Dan');">Steely Dan</a> was still topping the billboard charts.  No, mostly they are the talk of the town because Java doesn&#8217;t have them.  They&#8217;ve become a focus in the programming world because of the epic struggle to shoehorn them into the JDK.</p>
<p>In a nutshell, a closure is basically a high-order function.  It allows a function or a method to be treated as a first-class citizen of the language and passed as a parameter to other functions.  It also allows for this function to be used in algorithmic approaches to problem-solving, such as Map and Fold which will be discussed later.</p>
<p>One argument that many have is that Java has a bastardized form of closures now.  This may be true to an extent, but there are two problems with this:  1) the implementation now is a verbose mess and 2) scope.   It is getting better in <a href="http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html');">Java 8</a>, but gauging by the long, arduous and litigious morass that begat Java 7, I’m guessing we’ll see Java 8 just in time for the nuclear winter.</p>
<p>First, verbosity.  Following is how you would implement an anonymous inner class in Java for an actionListener:</p>
<p><code>Button b = new Button();<br />
b.addActionListener(new ActionListener() {<br />
public void actionPerformed(ActionEvent e) {<br />
// Code here<br />
}<br />
});</code></p>
<p>Yikes, that is a whole lot of nonsense and I mercifully left out the actionPerformed code.  Not to mention that we are creating a class here, lugging around all the overhead that comes with it.</p>
<p>Secondly, and most importantly, is the idea of scope.  An anonymous inner class can refer to variables outside the class, but since the class could technically live long after the enclosing class falls out of scope, the variables must be final.  So, something like this is legal:</p>
<p><code>final int outerVar = 0;<br />
Button b = new Button();<br />
b.addActionListener(new ActionListener() {<br />
public void actionPerformed(ActionEvent e) {<br />
int counter = outerVar + 1;<br />
}<br />
});</code></p>
<p>However, because the ‘outerVar’ variable is final, this prevents modification to immutable reference types and primitives, which at times can be limiting.  This runs counter to a true closure in other languages that binds itself to the enclosing environment and allows for unfettered access to these variables.</p>
<h4>Recursion</h4>
<p>The idea of recursion is a calling card of functional programming.  The reason it is the de rigueur approach to iteration is because of immutability.  Maintaining a loop counter or a hasNext boolean requires mutable state.  Yeah, I wasn&#8217;t kidding when I said functional programming focused on immutability, was I?</p>
<p>Matters are made easier when we consider the above point about Lists and Maps.  Lists and Maps are easily implemented with recursion and it just so happens they are the central focus of functional programming.</p>
<p>The one problem with recursion is that performance is not very good.  It is also susceptible to stack overflows if not properly implemented.  Luckily, certain languages such as <a href="http://haskell.org/haskellwiki/Haskell" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://haskell.org/haskellwiki/Haskell');">Haskell </a>and <a href="http://www.scala-lang.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.scala-lang.org/');">Scala </a>can generate code that represents a loop or eliminate the necessity to produce a new stack frame with every recursion.  This is known as tail call optimization and can be employed when the recursive call is the last statement in the function.  Java, alas, does not support tail call optimization.  Do I hear <a href="http://en.wikipedia.org/wiki/Kid_Charlemagne" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Kid_Charlemagne');">Kid Charlemagne</a> playing in the background?</p>
<h4>Combinators / Concepts</h4>
<p>In addition to recursion, there are certain functions and algorithms that are endemic to functional programming.  Algorithms such as Fold, Map, Filter, and Reduce are functions that can be performed on all elements in a collection to produce a new collection of results.  For example, Fold will ‘fold’ each element on top of the one next to it to produce a new value.  The resultant value is then folded again onto the next element in the same direction to produce yet another value.  This approach can be used for example to sum up the numbers in a list.</p>
<p>Map can apply a defined function to each element in a list, such as squaring the element it finds.  So, a function is defined as say ‘x * x’ and then it is ‘mapped’ to a collection.   The result is a collection of the same size with each element squared.</p>
<p>Other functions such as Filter and Reduce apply a function to elements, returning a collection of equal or lesser size with elements inside that were returned as a result of the Filter function.</p>
<table border="0">
<tbody>
<tr>
<td><img class="aligncenter size-medium wp-image-3969" src="http://www.summa-tech.com/blog/wp-content/uploads/2011/11/fold-300x185.png" alt="fold" width="300" height="185" /></td>
<td><img class="aligncenter size-medium wp-image-3972" src="http://www.summa-tech.com/blog/wp-content/uploads/2011/11/map-with-label-270x300.png" alt="map-with-label" width="165" height="185" /></td>
</tr>
</tbody>
</table>
<h4>Concurrency</h4>
<p>So, OK, immutability can only get you so far.  Scenarios are bound to occur where you uhhh, actually need to CHANGE something.  Fear not, compadre, functional programming again has you covered.  Two main approaches to concurrency to which functional programming subscribes are the actor model and the software transactional model.</p>
<p>The actor model relies on the idea of an actor of change that serves as your representative to changing data.  Need to increment an integer, send a message to the actor.  Need to change an address, send the actor a message.  Its up to him to coordinate the changes to the data.  Rather than have a multitude of callers all banging away at a certain state, they all must coordinate change through the actor.</p>
<p>The astute of you out there will cry foul and say that the actor is going to be a bottleneck in the process.  And yes, I would say, that was my impression also.  Thankfully, there are whole frameworks built around the actor model that handle this for you.  For example, <a href="http://akka.io/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://akka.io/');">Akka</a>, which is representative of the Scala concurrency framework, is an implementation of the actor model.</p>
<p>Another such functional programming approach to concurrency is the software transaction model.  STM deserves its own blog post, but just know that it involves tracking state changes over time.  Only references to values are changes and even then, through strict synchronization techniques.  STM is akin to database locking in that other transactions cannot view the data in an intermediate state.  Some functional languages employ STM and Clojure even has it built into the core language.</p>
<p>So, yes, functional programming can be a dry topic, but if you are truly interested in learning new things and new approaches to solving problems, it is a veritable gold mine of concepts.  It takes a bit to grasp, and probably a lifetime to master, but as Steve Jobs colloquialized, ‘the journey is the reward’.  And its probably best to begin the journey before the letter switches again and you need a whole new encyclopedia.</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/8Rjv13k0ZfI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/11/28/the-power-of-functional-thinking-an-ode-in-fn-parts/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/11/28/the-power-of-functional-thinking-an-ode-in-fn-parts/</feedburner:origLink></item>
		<item>
		<title>Usability Testing on Agile Projects (part 1)</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/hUZH7XdLgZ4/</link>
		<comments>http://www.summa-tech.com/blog/2011/11/20/usability-testing-on-agile-projects-part-1/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 02:47:33 +0000</pubDate>
		<dc:creator>Ben Northrop</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[agile]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[Scrum]]></category>

		<category><![CDATA[usability]]></category>

		<category><![CDATA[user interface]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3865</guid>
		<description><![CDATA[It is not enough that we deliver systems that are merely functional, they must also be usable. Paraphrasing from usability expert <a href="http://www.codinghorror.com">Jeff Attwood</a>, to the users of the system, "the interface is the application"; it is their most visible window into our work. Whether we finish on time, on budget, or in scope can be immaterial if the final deliverable is frustrating or inefficient to use.

On most enterprise applications, in my experience, usability is promoted via a number of low-cost methods: following usability standards, deferring to user interface specialists, trusting our intuitions, or simply conferring with customers and business owners. And while these methods are sufficient in most cases, when usability is a high priority, there is simply no substitute for actually watching people, without interference, use the software we build. This is the practice of <a href="http://en.wikipedia.org/wiki/Usability_testing">usability testing</a>.
]]></description>
			<content:encoded><![CDATA[<p>It is not enough that we deliver systems that are merely functional, they must also be usable. Paraphrasing from usability expert <a href="http://www.codinghorror.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.codinghorror.com');">Jeff Attwood</a>, to the users of the system, &#8220;the interface is the application&#8221;; it is their most visible window into our work. Whether we finish on time, on budget, or in scope can be immaterial if the final deliverable is frustrating or inefficient to use.</p>
<p>On most enterprise applications, in my experience, usability is promoted via a number of low-cost methods: following usability standards, deferring to user interface specialists, trusting our intuitions, or simply conferring with customers and business owners. And while these methods are sufficient in most cases, when usability is a high priority, there is simply no substitute for actually watching people, without interference, use the software we build. This is the practice of <a href="http://en.wikipedia.org/wiki/Usability_testing" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Usability_testing');">usability testing</a>.</p>
<p>In particular, I believe that usability testing should be strongly considered on projects where&#8230; </p>
<ol>
<li>The user base of the system is <i>numerous, not technically-savvy, or external</i> to the customer. </il>
<li>The cost of <i>user error</i> is high (e.g. software for managing financial transactions, medical procedures, etc.) and features are complex.</il>
<li>The <i>UI framework</i> or paradigm is nascent or highly flexible (e.g. RIA, iPhone, etc.) and a consensus on usability patterns or best practices has not yet been reached.</il>
</ol>
<p>In addition to making our products easier to use, usability testing can also be of great benefit to us, the developers of the software, by improving our usability intuitions, educating us on the functional domain and application of the software we build, and re-enforcing for us that what we create has a tangible impact on real people. </p>
<p>In this post I&#8217;ll describe usability testing within <a href="http://en.wikipedia.org/wiki/Agile_management" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Agile_management');">agile projects</a> from a project management perspective, describing how to estimate, prioritize, and &#8220;burn-down&#8221; the usability test.  In a follow-on post, I&#8217;ll dig into the actual activity of usability testing, breaking down some best practices within the framework of a simple 3-step process: (1) plan for the test, (2) perform the test, and (3) analyze the results.  Let&#8217;s get started&#8230;</p>
<h3>Managing Usability Testing with Scrum</h3>
<p>Effective usability testing can be <a href="http://24ways.org/2006/fast-and-simple-usability-testing" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://24ways.org/2006/fast-and-simple-usability-testing');">easy</a>, <a href="http://24ways.org/2006/fast-and-simple-usability-testing" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://24ways.org/2006/fast-and-simple-usability-testing');">quick</a>, <a href="http://www.useit.com/papers/guerrilla_hci.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.useit.com/papers/guerrilla_hci.html');">cheap</a>, and, as the diagram below shows, can fit seamlessly within the <a href="http://en.wikipedia.org/wiki/Scrum_(development)" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Scrum_(development)');">Scrum methodology</a>.  Here are some tips, given my experiences with usability testing on Agile projects, on how this can be achieved:</p>
<p><br/></p>
<div align="center">
<a href="http://www.summa-tech.com/blog/wp-content/uploads/2011/11/scrum_and_usability_testing.gif"  target="_blank"><img src="http://www.summa-tech.com/blog/wp-content/uploads/2011/11/scrum_and_usability_testing-300x223.gif" alt="scrum_and_usability_testing" title="scrum_and_usability_testing" width="300" height="223" class="aligncenter size-medium wp-image-3874" /></a><br />
(<a href="http://www.summa-tech.com/blog/wp-content/uploads/2011/11/scrum_and_usability_testing.gif"  target="_blank">click</a> to expand)
</div>
<p><b>Usability Test as Backlog Item:</b> Unlike other development best practices (like code reviews or unit testing), usability testing should, in my opinion, not be &#8220;built-in&#8221; as a part of normal development tasks, but rather should be treated as a separate <a href="http://www.mountaingoatsoftware.com/scrum/product-backlog" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.mountaingoatsoftware.com/scrum/product-backlog');">backlog item</a> - given an estimate by the development team, a priority by the business owners, and is assigned to a sprint for completion. Unlike other backlog user stories or tasks, however, usability testing has the property that it is never truly &#8220;done&#8221; - there are cases when (indeterminately) many rounds should be performed, and so the task of usability testing should never really be permanently plucked from the backlog.  </p>
<p><b>Estimation:</b>  Although the amount of time it takes to perform a usability test depends on many project factors (e.g. scope or complexity of the application, availability of users, etc.), in my experience (using the methodology to be laid out in the next post) effective usability testing can usually be completed with roughly 30 man-hours of work: 15 for the preparation, 10 for the test itself, and 5 for the analysis and communication of results. </p>
<p><b>Prioritization: </b> Oftentimes, even when usability testing should be performed (see above), business owners or other project stakeholders will still be reluctant or apprehensive to do so - especially when other methods (like just trusting intuitions) are cheaper and seem just as effective. It is important in these cases to stress that (a) <a href="http://www.useit.com/alertbox/20030825.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.useit.com/alertbox/20030825.html');">usability is important</a>, (b) we are notoriously bad judges of what is usable (too technical, too close to the system, etc.) and (c) usability testing can be cheap and extremely fruitful. Further, it is crucial to note that the earlier in the lifecycle that usability issues are identified, the easier they are to resolve - for example, redesigning a system&#8217;s confusing navigation structure once it is in production can be extremely costly and risky. In the end, however, usability testing should be prioritized along side all other user stories on the backlog, and this prioritization should be driven by the product or business owner.</p>
<p><b>Usability Testing as a Burndown Task: </b> Once usability testing has been selected for inclusion in a sprint, it should be assigned to one developer (where in agile teams, &#8220;developer&#8221; can mean tester, programmer, UI designer, etc.). Note that all activities of usability testing (planning, testing, and analysis) should fit within one sprint, and the task should be &#8220;burned-down&#8221; like any other development task. The practice of usability testing does not require an &#8220;expert&#8221;. <a href="http://sensible.com/downloads/DMMTchapter09_for_personal_use_only.pdf" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://sensible.com/downloads/DMMTchapter09_for_personal_use_only.pdf');">Anyone is capable</a> of performing one, and in fact, should if given the opportunity - it can be a rewarding and broadening experience.</p>
<p><b>Incorporating Feedback: </b>  Once the usability test is performed, observations from the test will be analyzed and discussed (see next post), and eventually some consensus will be achieved regarding how the application should change to improve user experience or efficiency.  This feedback can flow back through the Scrum development process in one of two forms: either as (1) new <a href="http://en.wikipedia.org/wiki/User_story" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/User_story');">user stories</a> added to the backlog (e.g. &#8220;as a customer, I want to be able to use wild cards in text searches&#8221;) or, when improvements are simple, as (2) bugs managed by the defect tracking system (e.g. &#8220;error messages should be red, not yellow&#8221;).  </p>
<p>As always, I&#8217;d be happy to hear about your experiences with usability testing on Agile projects.  How often do you usability test?  How do you track it from a project management perspective?  Please share! </p>
<p>Also, check back in a few weeks for <a href="http://www.summa-tech.com/blog/2012/01/04/usability-testing-on-agile-projects-part-2/" >part 2</a> where I&#8217;ll dig in to the actual practice of usability testing in more detail.  </p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/hUZH7XdLgZ4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/11/20/usability-testing-on-agile-projects-part-1/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/11/20/usability-testing-on-agile-projects-part-1/</feedburner:origLink></item>
		<item>
		<title>De-mystify the Benefits of BRMS</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/tH5zQFZYluE/</link>
		<comments>http://www.summa-tech.com/blog/2011/11/10/de-mystify-the-benefits-of-brms/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 21:48:28 +0000</pubDate>
		<dc:creator>Via Tsuji</dc:creator>
		
		<category><![CDATA[Process Integration]]></category>

		<category><![CDATA[brms]]></category>

		<category><![CDATA[ILOG]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3833</guid>
		<description><![CDATA[All technologies go through the life cycle of maturity and adoption. For most technologies, over-enthusiasm or “hype” and subsequent disappointment precedes mainstream adoption and realization of how the technology solves real business problems. Gartner has modeled this evolution in the Hype Cycle and identified distinct key phases (Gartner).

Business Rule Management Systems (BRMS) began the descent towards the “Trough of Disillusionment” in 2011 (Dixon &#38; Jones, 2011), wherein many implementations fail to deliver what businesses expected it could.

The focus of this series is to provide guidelines for truly reaping the benefits of a business rule management system. It clarifies certain implementation steps, debunks unrealistic expectations, and warns of common pitfalls to a BRMS implementation.

The first part of this series tackles the common pitfalls related to unrealistic expectations of BRMS, how to avoid them and distinguishing the true benefits of a BRMS  implementation from the market hype. ]]></description>
			<content:encoded><![CDATA[<div class="seriesmeta">This entry is part 1 of 1 in the series <a href="http://www.summa-tech.com/blog/series/reaping-the-benefits-of-brms/"  title="series-316">Reaping the Benefits of BRMS</a></div><p>A business rule management system (BRMS) is a software system used to define, deploy, execute, monitor and maintain variable and complex decision logic used by operational systems in an enterprise (Stineman, 2009). At a minimum, a BRMS is composed of the following components:</p>
<ul>
<li><strong>Repository. </strong>It encapsulates the decision logic or rules, external to the core application code, such that it can be shared and reused across the organization.</li>
<li><strong>User Tools. </strong>Tooling allows the Line of Business (LOB) and Information Technology (IT) groups to define and manage decision logic.</li>
<li><strong>Runtime Environment. </strong>The runtime engine allows production systems to access and execute decision logic overseen by the BRMS.</li>
</ul>
<div>
<div>Often, BRMS vendors advertise the top benefits of a BRMS to include the following:</div>
<div>
<ul>
<li>Reduce or remove the reliance on IT for changes in live systems</li>
<li>Increase LOB control over implemented decision logic for compliance and business management</li>
<li>Express decision logic with increased precision, using business vocabulary or graphical rule representations</li>
<li>Improve process efficiency</li>
</ul>
</div>
<div>Though many of these benefits can be achievable with a BRMS, the realization of these advantages relies heavily upon the enterprise – its processes, its people, and how the BRMS is implemented and managed within the organization.</div>
<div>
<div>
<ul>
<li><strong>Reliance on IT. </strong>BRMS must never translate to “no reliance” on the IT department. The BRMS itself needs to be installed and maintained by IT. The applications that need to invoke the decision logic encapsulated within the BRMS must be developed by IT. And the design of the decision logic (as well as the business user interface) cannot be done without IT help. However, once the BRMS and the rule-based applications are in place and depending on rule governance, the business users can manage the decision logic relatively independent of IT.</li>
<li><strong>Increased decision logic control. </strong>Increased LOB control over decision logic is limited to rules and applications already integrated with the BRMS. Business users cannot enable a new rule-based application through the system. It requires IT intervention. The BRMS only provides the tooling for business users to maintain rules as well as the runtime engine to execute them, but the application needs to be modified to become rule-based.</li>
<li><strong>Precise decision logic. </strong>Increased precision in rule expression also cannot be done by simply installing a BRMS. Object modeling by both the LOB and IT are required to effectively provide the basis of defining the decision logic. The BRMS simply provides the mechanisms to recognize the object model and define the rules. Different BRMS provides support for this benefit in different ways.</li>
<li><strong>Efficient Processes. </strong>Increase in decision automation may lead the way to process efficiency, but it largely depends on how the process is designed and what decision points are selected for automation. The BRMS alone cannot define the process and the deciding factors, but it can provide various options for integration and execution that assist with the goals of process efficiency. Occasionally, BRMS vendors prescribe best practices and/or methodologies that help with process design.</li>
</ul>
</div>
<p>Business rule management systems can undeniably benefit enterprises with real business problems associated with highly variable and complex decision logic. Avoid the common pitfalls of being clouded by unrealistic expectations. Understand the true benefits and limitations of a BRMS. Clarify what the system can offer with what the organization can support. Communicate this to the enterprise to ensure everyone is on the same page. And reap the benefits of a successful BRMS implementation!</p></div>
</div>
<h4>References</h4>
<p>Dixon, J., &amp; Jones, T. (2011, July 25) <em>Hype Cycle for Business Process Management, 2011</em>.</p>
<p>Gartner. (n.d.). <em>Gartner Hype Cycle</em>. Retrieved February 21, 2011, from Gartner: <a href="http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp');">http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp</a></p>
<p>Stineman, B. (2009, November). <em>IBM WebSphere ILOG Business Rule Management Systems: The Case for Architects and Developers</em>. Retrieved February 18, 2011, from IBM: <a href="ftp://ftp.software.ibm.com/common/ssi/sa/wh/n/wsw14072usen/WSW14072USEN.PDF" onclick="javascript:pageTracker._trackPageview('/outbound/article/ftp://ftp.software.ibm.com/common/ssi/sa/wh/n/wsw14072usen/WSW14072USEN.PDF');">ftp://ftp.software.ibm.com/common/ssi/sa/wh/n/wsw14072usen/WSW14072USEN.PDF</a></p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/tH5zQFZYluE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/11/10/de-mystify-the-benefits-of-brms/feed/</wfw:commentRss>
	
		<series:name><![CDATA[Reaping the Benefits of BRMS]]></series:name>
	<feedburner:origLink>http://www.summa-tech.com/blog/2011/11/10/de-mystify-the-benefits-of-brms/</feedburner:origLink></item>
		<item>
		<title>Using Page Objects with Selenium and Web Driver 2.0</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/7U5rDtQ3syc/</link>
		<comments>http://www.summa-tech.com/blog/2011/10/10/using-page-objects-with-selenium-and-web-driver-20/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 15:12:52 +0000</pubDate>
		<dc:creator>James Cox</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Selenium]]></category>

		<category><![CDATA[testing]]></category>

		<category><![CDATA[Web Driver]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3743</guid>
		<description><![CDATA[The Page Objects design pattern is outlined in the <a href="http://code.google.com/p/selenium/wiki/PageObjects">Selenium wiki</a>, but  to summarize, Page Objects are meant to encapsulate the messy internal state of a page.  Changes in the presentation code should only require changes only to the Page Objects, not to the actual test code.  Using a Page Object promotes consistency;  there may be five different ways to legitimately determine that you are on the login page, but adhering to the one definition in the Page Object will prevent you from having to maintain the other variants.

Page Objects should be ignorant of an application's business logic, they should only be aware of page state and how to interact with it.  By clearly delineating the test code from the page objects, you will be able to use the same page objects in a variety of tests cases and achieve code re-use.]]></description>
			<content:encoded><![CDATA[<h2>Page Objects</h2>
<p>The Page Objects design pattern is outlined in the <a href="http://code.google.com/p/selenium/wiki/PageObjects" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://code.google.com/p/selenium/wiki/PageObjects');">Selenium wiki</a>, but  to summarize, Page Objects are meant to encapsulate the messy internal state of a page.  Changes in the presentation code should only require changes only to the Page Objects, not to the actual test code.  Using a Page Object promotes consistency;  there may be five different ways to legitimately determine that you are on the login page, but adhering to the one definition in the Page Object will prevent you from having to maintain the other variants.</p>
<p>Page Objects should be ignorant of an application&#8217;s business logic, they should only be aware of page state and how to interact with it.  By clearly delineating the test code from the page objects, you will be able to use the same page objects in a variety of tests cases and achieve code re-use.</p>
<h2>The Sample Code</h2>
<p>The application that we will be using is the <a href="http://s3browse.springsource.com/browse/maven.springframework.org/snapshot/org/springframework/security/spring-security-samples-contacts/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://s3browse.springsource.com/browse/maven.springframework.org/snapshot/org/springframework/security/spring-security-samples-contacts/');">Spring Security Contact Example</a> that I deployed locally in a Tomcat 6 container.  No modifications of the web archive are necessary.</p>
<p>The first two classes are Page Objects: the Login Page and the Home Page.  Both pages validate that the page is currently loaded by checking the current page&#8217;s title.  A Page Object&#8217;s validation code may execute before the page has been loaded in the browser, so we will leverage the WebDriver asynchronous validation mechanism.  Both Pages will wait up to thirty seconds, polling every two seconds to see if the expected title is present before giving up.  WebDriver used to have a somewhat klunky way of doing this, but the new FluentWait and ExpectedConditions makes this code much more concise and readable.</p>
<p><strong>LoginPage.java</strong></p>
<pre name="code" class="java:nocontrols">
public class LoginPage {

	private final WebDriver driver;

	public LoginPage(WebDriver driver) {
		super();
		this.driver = driver;

		Wait wait = new FluentWait(driver)
	       .withTimeout(30, SECONDS)
	       .pollingEvery(2, SECONDS);

	     wait.until(ExpectedConditions.titleIs("Login"));
	}

	public HomePage loginAs(String username, String password) {

		executeLogin(username, password);
		return new HomePage(driver);
	}

	public void failLoginAs(String username, String password) {
		executeLogin(username, password);
	}

	private void executeLogin(String username, String password) {

		driver.findElement(By.name("j_username")).sendKeys(username);
		driver.findElement(By.name("j_password")).sendKeys(password);
		driver.findElement(By.name("submit")).submit();
	}

	public String getErrorMessage() {

		return driver.findElement(By.xpath("/html/body/p/font[@color='red']")).getText();
	}

}</pre>
<p><strong>HomePage.java</strong></p>
<pre name="code" class="java:nocontrols">
public class HomePage {

	private final WebDriver driver;

	private final static Logger logger = LoggerFactory
	.getLogger(HomePage.class);

	public HomePage(WebDriver driver) {
		super();
		this.driver = driver;

		Wait wait = new FluentWait(driver)
	       .withTimeout(30, SECONDS)
	       .pollingEvery(2, SECONDS);

	     wait.until(ExpectedConditions.titleIs("Your Contacts"));

	}

	public String getHomePageWelcomeMessage() throws Exception{

		return driver.findElement(By.xpath("/html/body/h1")).getText();

	}

}</pre>
<p>Each Page Object also contains an additional method that checks for the presence or content of an element.  The Page Object only locates and retrieves these values.  We will let the test case interpret the correctness of these values.</p>
<p>I&#8217;ve created a single junit test that will test a successful and unsuccessful login attempt.  The test instantiates a Firefox WebDriver to pass to the Page Objects.  In a more sophisticated test suite you would inject the WebDriver  implementation class to leverage the same test against different browsers.  To start each test, we navigate to a protected URI.  This should trigger the authentication process and bring the user to the login page.  After each test we make an attempt to clean up by accessing the logout URI and cleaning up any session cookies that remain in the browser.  Finally, after all of the tests are completed, we gracefully shutdown the WebDriver.</p>
<p><strong>LoginTest.java</strong></p>
<pre name="code" class="java:nocontrols">
public class LoginTest {

	private final static Logger logger = LoggerFactory.getLogger(LoginTest.class);
	private final static WebDriver driver = new FirefoxDriver();
	private final static String hostAndPortAndContext = "http://localhost:8081/spring-security-samples-contacts-3.0.8.CI-20110909.121734-1";
	private final static String securedURI = "/secure/index.htm";
	private final static String logoutURI = "/j_spring_security_logout";

	 @AfterClass public static void afterAllIsSaidAndDone() {
		 driver.quit();
	 }

	@After
	public void after() {
		driver.get(hostAndPortAndContext+logoutURI);
		driver.manage().deleteAllCookies();
	}

	@Before
	public void before() {
		driver.get(hostAndPortAndContext+securedURI);
	}

	@Test
	public void testLogin() throws Exception {

		LoginPage loginPage = new LoginPage(driver);
		HomePage homePage = loginPage.loginAs("rod", "koala");
		assertEquals("rod's Contacts",homePage.getHomePageWelcomeMessage());

	}

	@Test
	public void testFailedLogin() throws Exception {

		LoginPage loginPage = new LoginPage(driver);
		loginPage.failLoginAs("nobody", "WRONG");
		assertTrue(loginPage.getErrorMessage().contains("Reason: Bad credentials."));
	}

}</pre>
<p>Running the JUnit test will spawn an instance of Firefox to run the two test cases.  The browser will use a unique profile, so your tests will not be affected by your current browser cache or configuration.</p>
<h2>Shortcomings of Page Objects and Web Driver</h2>
<p>If you change the password of the valid user and re-run the test, you will need to wait the entire duration of the timeout period (currently thirty seconds) before moving onto the next test.  This is because the Home Page is only checking to see if the Home Page has loaded, not if the login page is being re-displayed with an error.  The problem with this is twofold</p>
<ul>
<li>it is unclear as to why a test failed.  You are only given a stack trace that indicates the expected Home Page element could not be loaded within the timeout period.  But what happened?  Was the account locked, was the server not up, or did the application blow up?  If you are watching the tests run, the underlying cause of failure may be obvious, but if you are running the tests on a CI server, or executing them remotely with  <a href="http://selenium-grid.seleniumhq.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://selenium-grid.seleniumhq.org/');">Selenium Grid.</a> it may be difficult to diagnose.</li>
<li>it takes a long time for the test to fail.  If the failure is on a main navigation path (e.g. Login) it will take a long time for all of the tests to fail.  Automated test suites that used to take 10 minutes to run on the CI server may now take several hours to complete before you are notified that something is wrong.</li>
</ul>
<p>Another concern is that we are now coupling page state/interaction with page flow.  The Login page executes the same login logic twice, once for failed logins, the other for successful logins.  Both methods do the same thing, but have different return types as the expected navigation outcome will be different.  So despite our best intentions, the validation of the business logic has leaked into the page objects.</p>
<p>We could code the page flow into a page builder class that can detect unexpected navigation flow.  This class could detect a failed user login due to a bad password.  But this solution quickly increases the complexity of the code.  The tidy one liner check now becomes a complicated check for the presence of a login error message in a try catch block.  Using a builder for main navigation flows (e.g. login) may have merit, but it becomes overkill to use as the default pattern.</p>
<p>Such a page builder class would not catch all unexpected navigation errors.  Unless you&#8217;ve defined custom error pages, the container can also render error pages.  These error pages are container specific; Tomcat will generate a different 404 page than Websphere.  Browsers can also render error pages.  For example, if the browser is unable to connect to a host  the browser will render a page indicating the failure.  The list of possible unexpected pages is quickly growing.</p>

<a href="http://www.summa-tech.com/blog/2011/10/10/using-page-objects-with-selenium-and-web-driver-20/screenshot-oops-google-chrome-could-not-connect-to-localhost9449-chromium/"  title='screenshot-oops-google-chrome-could-not-connect-to-localhost9449-chromium'><img src="http://www.summa-tech.com/blog/wp-content/uploads/2011/10/screenshot-oops-google-chrome-could-not-connect-to-localhost9449-chromium-150x150.png" width="150" height="150" class="attachment-thumbnail" alt="" /></a>
<a href="http://www.summa-tech.com/blog/2011/10/10/using-page-objects-with-selenium-and-web-driver-20/screenshot-problem-loading-page-mozilla-firefox/"  title='screenshot-problem-loading-page-mozilla-firefox'><img src="http://www.summa-tech.com/blog/wp-content/uploads/2011/10/screenshot-problem-loading-page-mozilla-firefox-150x150.png" width="150" height="150" class="attachment-thumbnail" alt="" /></a>

<p>It would be nice if the actual Driver implementation could identify browser generated error pages.  It would also be possible to expose the HTTP Response code to identify server side errors.  Unfortunately, it does not appear that this functionality will be appearing in Web Driver <a href="http://code.google.com/p/selenium/issues/detail?id=141" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://code.google.com/p/selenium/issues/detail?id=141');">any time soon.</a></p>
<p>It might be difficult to detect errors, but when they happen you can at least get the current content of the page.  This can be done by logging the contents of the frame with driver.getPageSource() or grabbing a screenshot with  getScreenshotAs().  The thought of associating screen shots to a test sound appealing and all of the major drivers (IE, Chrome and Firefox) support the getScreenShotAs method.  But it&#8217;s difficult to a harvest screenshots for inspection after a remote test run.  For the most part, taking a current page source dump should be sufficient to indicate current page state.</p>
<h2>Conclusions</h2>
<p>Page Objects do a good job of encapsulating the underlying page source, but not as well at modeling navigation flow.  Web Driver 2.0 and Selenium are continually improving.  Hopefully they will continue to do so by adding some of the missing features.</p>
<p>If you are not yet using PageObjects, consider doing so.  If you are not yet using Selenium, what are you waiting for?</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/7U5rDtQ3syc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/10/10/using-page-objects-with-selenium-and-web-driver-20/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/10/10/using-page-objects-with-selenium-and-web-driver-20/</feedburner:origLink></item>
		<item>
		<title>Micro Time Management: To-Dos and To-Don’ts</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/2y7v5fa4EGk/</link>
		<comments>http://www.summa-tech.com/blog/2011/10/04/micro-time-management-to-dos-and-to-donts/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 14:38:10 +0000</pubDate>
		<dc:creator>Brian Gray</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[agile]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[Pomodoro]]></category>

		<category><![CDATA[Scrum]]></category>

		<category><![CDATA[time management]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3715</guid>
		<description><![CDATA[One of the "softer" sides of development is time management. We do this on both a macro scale (project planning, estimates, what goes into the Sprint, etc.) and a micro scale (what am I going to work on today?). Most developers on most days are concerned with micro time management -- and many good project managers realize a lot of important decisions get made there as well ("it seemed like it would be a quick to fix so I went in and did it" or "Gina came over and asked me about this defect so I fixed it.").  This is especially true of programmers on many projects, a few teams, and with some maintenance and support involved in their work.

I do not profess to have a solution -- I thought I would share three strategies that I have tried over my career (I am sure there have been others). If you want to try one of these, great! Let me know how it goes! If you have another approach, please share or email!]]></description>
			<content:encoded><![CDATA[<p>One of the &#8220;softer&#8221; sides of development is time management. We do this on both a macro scale (project planning, estimates, what goes into the Sprint, etc.) and a micro scale (what am I going to work on today?). Most developers on most days are concerned with micro time management &#8212; and many good project managers realize a lot of important decisions get made there as well (&#8221;it seemed like it would be a quick to fix so I went in and did it&#8221; or &#8220;Gina came over and asked me about this defect so I fixed it.&#8221;).  This is <em>especially</em> true of programmers on many projects, a few teams, and with some maintenance and support involved in their work.</p>
<p>The problem is: time management, even on a small scale is hard. We spend a lot of time learning how to get good at macro time management and very carefully lay out our project priorities for the release and the iteration. But that means little if day to day the developers don&#8217;t have a good system to find the right balance of focus on those priorities versus just the right amount of focus on email, meetings, last-minute feature requests, needs from other projects, helping others on the team, etc.</p>
<p>I do not profess to have a solution &#8212; I thought I would share three strategies that I have tried over my career (I am sure there have been others).  If you want to try one of these, great! Let me know how it goes! If you have another approach, please share or email!</p>
<p><a href="http://www.summa-tech.com/blog/wp-content/uploads/2011/09/cowboy-1.png" ><img class="size-medium wp-image-3716 alignnone" style="margin-top:30px; margin-right: 10px;margin-bottom: 10px;" src="http://www.summa-tech.com/blog/wp-content/uploads/2011/09/cowboy-1-300x240.png" alt="Method #1: Cowboy Method" width="210" height="168" /></a></p>
<h3>Cowboy Style</h3>
<p>When I first started at Summa, I did not have a system for how to manage my time. I let tasks come in and go out &#8212; mostly just remembering what I had promised to get done and when it was due. To help, I would star or label emails and maintain a few lists.  I am organized and careful so this worked out for a while, but it did not take long for the system to start buckling with the weight of what I was asking it to do.</p>
<p>Within my first year, I had a 2 or 3 week period where I was helping out on three different projects &#8212; and keeping emails straight was not going to cut it. Thankfully, approach #2 entered my life soon after&#8230;</p>
<p><a href="http://www.summa-tech.com/blog/wp-content/uploads/2011/09/scrum-2.png" ><img class="size-medium wp-image-3718 alignnone" style="margin-top:30px; margin-right: 10px;margin-bottom: 10px;" src="http://www.summa-tech.com/blog/wp-content/uploads/2011/09/scrum-2-300x195.png" alt="2 - Scrum Method" width="216" height="140" /></a></p>
<h3>Scrum Method</h3>
<p><a href="http://en.wikipedia.org/wiki/Scrum_(development)" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Scrum_(development)');" target="_blank">Scrum</a> is an agile technique for managing teams and projects. It&#8217;s goal is not to be prescriptive about anything, let alone my day, but I found that it&#8217;s philosophies were having a radical impact on the way I organized myself.</p>
<p>It&#8217;s hard to explain how without a deep understanding of what being on a Scrum team feels really feels like. I don&#8217;t know who you are &#8212; maybe you&#8217;ve been on Scrum teams maybe not. I don&#8217;t want to teach you the basics, but I do want to explain how they revolutionized my day.</p>
<p>One thing a Scrum team does is have a daily <a href="http://martinfowler.com/articles/itsNotJustStandingUp.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://martinfowler.com/articles/itsNotJustStandingUp.html');" target="_self">stand-up meeting</a>. During this meeting, each team member announces what they did since the previous stand-up, what they will do before the next, and any impediments in their way. At first, I just went through the motions, but as I understood what it was <em>about</em>, it really started to change things. Here are some important points:</p>
<ul>
<li>I talk about what I <em>will do </em>before the next meeting. I was used to saying, &#8220;I will continue work on the User DAO.&#8221; But my friendly compatriots would not let that slide. The stand-up is about making commitments to the team, and breaking your tasks into day-size (or smaller) chunks. Set a goal for what you will (and can) accomplish before the next meeting. Lofty endless goals do not cut it.</li>
<li>It is also an exercise in focus. Because I made that commitment to the team, it is that same team I need to face if I have not achieved one of those goals. This is not scary &#8212; they understand when it takes longer than expected or I ran into trouble. But if I got distracted by a feature someone stopped in to ask about, or a bug I found, they are there to put me back on track.</li>
<li>I also now have a list of tasks &#8212; done and to do &#8212; and I am writing them each day in a growing <a href="http://office.microsoft.com/en-us/onenote-help/demo-what-is-onenote-HA010168634.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://office.microsoft.com/en-us/onenote-help/demo-what-is-onenote-HA010168634.aspx');" target="_blank">OneNote</a> list. Each time I run out, I can go back to the Sprint backlog, whether it lives in a spreadsheet or (preferably) <a href="http://www.rallydev.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.rallydev.com/');" target="_blank">Rally</a> to pull out my next story.</li>
<li>Scrum also gives us a win-win solution to the daily issues that come up. If a last minute defect or request comes up, I used to have to choose between fixing it now (at the expense of my current work and context) or adding it to a list and potentially forgetting it. Now, we can safely add it to the product backlog. While it is outside of the Sprint scope, the product owners know it will be there for them to prioritize at the next Sprint planning and I can continue on developing happily!</li>
</ul>
<p><a href="http://www.summa-tech.com/blog/wp-content/uploads/2011/09/pomodoro-3.png" ><img class="size-medium wp-image-3717 alignnone" style="margin-top:30px; margin-right: 10px;margin-bottom: 10px;" src="http://www.summa-tech.com/blog/wp-content/uploads/2011/09/pomodoro-3-300x232.png" alt="3 - Pomodoro Method" width="216" height="167" /></a></p>
<h3>Pomodoro Technique</h3>
<p>After a handful of years, the Scrum method was still leaving something to be desired. Mainly:</p>
<ul>
<li>I would still find myself with days where I had accomplished none or few of my committed tasks</li>
<li>I would occasionally be thrown back in the Wild West &#8212; multiple projects, multiple demands, no backlogs of any kind. Scrum method doesn&#8217;t really help you out there.</li>
</ul>
<p>I was then fortunate enough to hear a <a href="http://www.youtube.com/user/javaposse#p/search/0/lb2GWtfdXzU" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.youtube.com/user/javaposse#p/search/0/lb2GWtfdXzU');" target="_blank">lightning talk</a> about the <a href="http://www.pomodorotechnique.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.pomodorotechnique.com/');" target="_blank">Pomodoro Technique</a>. There are many parts to the technique, but the part that most interested me was the focus on micro-micro time management. Here are some highlights:</p>
<ul>
<li>Break down your daily tasks into subtasks that can be performed in ~25 minutes.</li>
<li>Choose a task and set your pomodoro timer (pictured at the left, looks like a tomato &#8212; or pomodoro, in Italian) for 25 mins.</li>
<li>This is an intensive period. Some pomodoros can be focused on checking email or following up with someone on a debugging problem, but otherwise you disregard all distraction from the task at hand.</li>
<li>Each second the mechanical timer ticks, reminding you to focus on the task in front of you.</li>
<li>At 25 mins, the timer rings, and you take a break.</li>
</ul>
<p>When I heard about it, I was excited. It sounded fantastic. In practice, I find I can only do it in short bursts. I often find the focus amazingly helpful. But it is hard to get much done in 25 mins. Many of my tasks are &#8220;continue on from the last task.&#8221; The biggest help is that every 25 mins I am reminded of my progress throughout the day, and my progress against my original plan. When I start to veer off course, I can see it early, even when I can&#8217;t help it.</p>
<div>
<p>So currently, I use a mix of all 3. Please feel free to comment and/or share your own techniques!</p>
<p>* &#8220;On the bench&#8221; refers to time that us consultants spend working on the home office when not on a customer engagement.</p></div>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/2y7v5fa4EGk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/10/04/micro-time-management-to-dos-and-to-donts/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/10/04/micro-time-management-to-dos-and-to-donts/</feedburner:origLink></item>
		<item>
		<title>Great Things Are Happening at Summa</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/YEPMFCY-hAI/</link>
		<comments>http://www.summa-tech.com/blog/2011/09/28/great-things-are-happening-at-summa/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 14:02:58 +0000</pubDate>
		<dc:creator>Karen Colson</dc:creator>
		
		<category><![CDATA[Summa]]></category>

		<category><![CDATA[awards]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3699</guid>
		<description><![CDATA[September 2011 marks Summa’s 15<sup>th</sup> Anniversary and we have a lot of exciting things happening at the company.  We’ve received accolades locally and nationally for our sales and employee growth, along with recognition of Summa as a great place to work.]]></description>
			<content:encoded><![CDATA[<p>September 2011 marks Summa’s 15<sup>th</sup> Anniversary and we have a lot of exciting things happening at the company.  We’ve received accolades locally and nationally for our sales and employee growth, along with recognition of Summa as a great place to work.</p>
<p>In August, Summa was ranked on the <a href="http://www.summa-tech.com/news/2011inc5000ranking-pr.php4" >Inc 500|5000 list</a>.  We were recognized for our sales growth over the past three years of 75%.  We were also ranked on the <a href="http://www.bizjournals.com/pittsburgh/news/2011/08/26/pittsburgh-100-winners-honored.html?page=all" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.bizjournals.com/pittsburgh/news/2011/08/26/pittsburgh-100-winners-honored.html?page=all');">Pittsburgh 100</a>, a list of the fastest-growing, privately held companies in Pittsburgh.  In addition to our sales growth, we’ve experienced employee growth of 66%.</p>
<p>Adam Menzies, a Solution Architect at Summa, was recognized by Sheetz at their Annual Vendors Days. Adam was given the “Sheetz IT Vendor of the Year” Award, acknowledging the work he did on several key initiatives for Sheetz.</p>
<p>Last week at the Consol Energy Center, we attended the Pittsburgh Technology Council’s <a href="http://tech50.pghtech.org/finalists/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://tech50.pghtech.org/finalists/');">Tech 50 </a>Event, where we were named as a finalist for the Technology Accelerator of the Year.</p>
<p>In October, we will be recognized by the <a href="http://www.bizjournals.com/pittsburgh/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.bizjournals.com/pittsburgh/');">Pittsburgh Business Times</a> as one of the Best Places to Work in Western Pennsylvania.  We are thrilled to be named to this list for the fifth year in a row.</p>
<p>As I said, great things are happening at Summa.  It&#8217;s been an exciting 15 years and we look forward to all the opportunities ahead.</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/YEPMFCY-hAI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/09/28/great-things-are-happening-at-summa/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/09/28/great-things-are-happening-at-summa/</feedburner:origLink></item>
		<item>
		<title>Chicken Soup for the Caching Soul</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/k3ej4OzEwGM/</link>
		<comments>http://www.summa-tech.com/blog/2011/09/12/chicken-soup-for-the-caching-soul/#comments</comments>
		<pubDate>Mon, 12 Sep 2011 14:15:07 +0000</pubDate>
		<dc:creator>Steve Ayers</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[caching]]></category>

		<category><![CDATA[database]]></category>

		<category><![CDATA[hibernate]]></category>

		<category><![CDATA[ORM]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3622</guid>
		<description><![CDATA[When last we saw our hero, he was riding off into the sunset with <a href="http://www.hibernate.org/">Hibernate</a>, his newfound love.  The blogosphere was all abuzz.  Would this new relationship blossom into something so well-known, tabloids would invent a new name for it?  (HibeAyersnate?   JBAyers?).  Or would the union crash and burn, a steaming wreck amidst so many Hollywood romances?  (I'm looking at you, J-Lo).

Well, neither really, faithful reader.  Our hero is neither smitten nor inflamed with that finicky ORM.  There are still times when he hears of Hibernate arrogantly committing data merely because it felt like it, while other times, he simply joins two tables through a simple line in XML.  It’s a slippery slope.  Who said true love was easy?]]></description>
			<content:encoded><![CDATA[<p>When <a href="http://www.summa-tech.com/blog/2011/06/07/dr-mindbender-or-how-i-learned-to-stop-worrying-and-love-hibernate/" >last we saw</a> our hero, he was riding off into the sunset with <a href="http://www.hibernate.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.hibernate.org/');">Hibernate</a>, his newfound love.  The blogosphere was all abuzz.  Would this new relationship blossom into something so well-known, tabloids would invent a new name for it?  (HibeAyersnate?   JBAyers?).  Or would the union crash and burn, a steaming wreck amidst so many Hollywood romances?  (I&#8217;m looking at you, J-Lo).</p>
<p>Well, neither really, faithful reader.  Our hero is neither smitten nor inflamed with that finicky ORM.  There are still times when he hears of Hibernate arrogantly committing data merely because it felt like it, while other times, he simply joins two tables through a simple line in XML.  It’s a slippery slope.  Who said true love was easy?</p>
<p>But, friends, today, we gather to praise Hibernate, not to bury it.  For today, we will discuss in detail one of the characteristics which truly makes Hibernate a worthwhile comrade.  That something is Caching.</p>
<p>Hibernate operates on three levels of caching, First-Level (or Session), Second-Level (or Object), and Query Caching.  Each has their own jurisdiction and each has their own advantages.  They even work together to provide a powerful and flexible approach to application performance.  So, today, we&#8217;ll go through each to paint a clearer picture about an area in which Hibernate shines.  </p>
<p>But, the Intergoogles is rife with information about caching:  how to configure it, how it works, why it’s awesome.  I won&#8217;t belabor the point.  Instead, I will focus on what you need to know about the three levels of caching.  I&#8217;ll illustrate the <a href="http://en.wikipedia.org/wiki/Gotcha_(programming)" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Gotcha_(programming)');">Gotchas</a>, the <a href="http://en.wikipedia.org/wiki/A-ha" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/A-ha');">AHA</a>!&#8217;s, and the <a href="http://en.wikipedia.org/wiki/Sha_Na_Na" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Sha_Na_Na');">Sha Na Na&#8217;s</a>.  </p>
<p>I will assume that by now you know what caching is and why it is important.  If not, here&#8217;s a sentence you can cut out and keep in your wallet or purse the next time your grandmother asks you to explain the benefits of caching (right after she figures out her answering machine):</p>
<div style="border-style:dotted;border-width:1px;margin-top:5px;margin-bottom:5px"><em>&#8216;Caching is the process of storing frequently-accessed information in a separate area of memory that is easily and quickly accessible so that subsequent reads of the same information will take less time&#8217;</em></div>
<p>There, Gramma, that is caching.  Caching.  CACHING!  No, I didn&#8217;t sneeze, gramma.  No, I&#8217;m not sick.  [sigh] Yes, I&#8217;ll have the chicken soup.</p>
<p>Anyway, now you know what caching is.  So, why should you care?</p>
<h3>FIRST LEVEL CACHE</h3>
<p>First-Level caching in Hibernate is otherwise known as the session cache.  What this means is that Hibernate maintains a separate cache of objects as long as the same session is open.  </p>
<p><a href="http://www.summa-tech.com/blog/2011/06/07/dr-mindbender-or-how-i-learned-to-stop-worrying-and-love-hibernate/" >As I mentioned in my last verbose and rambling blog post</a>, this means that:</p>
<p><code>Session.load(MyObject.class, 123);<br />
// Other logic here<br />
Session.load(MyObject.class, 123); </code> </p>
<p>will produce the same result, but only hit the database once.  Hibernate&#8217;s first level cache realizes that you&#8217;ve already asked for this information in this session so it can merely pull what you retrieved previously.  Since this is the same session, then surely nothing has changed.  So, why make yet another round trip to the database only to return you information you already have?  </p>
<p>But, this is oversimplifying the matter, a practice that is commonplace on the internet when looking for guidance in technology.  &#8216;Just drop the JAR in your classpath and it all just works!&#8217;.  Sure it does, bud.  You forgot to mention I need nine other JARs, three XML files, and the moon must be a waxing gibbous.</p>
<p>To truly understand the first level cache, it is important to understand the duration and lifecycle of a Hibernate session.  I think that grasping this is critical to understanding this cache level because inherent in all this is a fundamental question that is integral to all caching approaches, which is the concept of cache invalidation.  You need to invalidate data in the cache when the real data in the database changes.  I don&#8217;t think it takes a rocket scientist to know that even though we are operating within our own session, there could be a multitude of other sessions alive.  All of which could be updating the very data sitting in your precious session.</p>
<p>So, how long is this session alive anyway?  If it’s open for any substantial length of time, the odds of stale data in the cache grow exponentially.  One would hope the session doesn&#8217;t live for very long.  Good news, it doesn&#8217;t.  </p>
<p>There is a pattern that Hibernate suggests to make efficient use of the Session Cache called <a href="http://community.jboss.org/wiki/OpenSessionInView" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://community.jboss.org/wiki/OpenSessionInView');">Open Session In View</a>.  In a nutshell, this means keeping the session open just long enough to render the view of the JSP.  The session is instantiated upon the HTTP request and then destroyed when the view is fully rendered.  Not bad, right?  So, now that we know how the session cache works and how long the session lives, lets look at some things to keep in mind:</p>
<ul>
<li>
<h4>The Session Cache has no built-in invalidation when data changes</h4>
<p>So, even though it is short-lived, it is still possible that another session has modified the data from the time you first requested it and the time you requested it again.  To make matters worse, Open Session In View actually keeps the session open LONGER than usual. </li>
<li>
<h4>It could be YOU updating the data behind the scenes</h4>
<p>Wait, what?  I&#8217;m READING table ABC, but I&#8217;m UPDATING XYZ.<br />
True, smart guy, but remember one of the banes of every developer’s existence: legacy databases.  Some of these databases contain business logic nestled deep within the friendly confines of those normalized monsters.  So while you think you&#8217;re innocently updating table XYZ, there are triggers or procedures going on behind the scenes that are changing table ABC right out from under your nose.  I&#8217;ve seen it happen.</p>
<p><img src="http://www.summa-tech.com/blog/wp-content/uploads/2011/09/session-level-cache1.png" alt="session-level-cache1" width="480" height="229" class="aligncenter size-full wp-image-3635" /></p>
<p>So, as you can see, a simple update to the BAZBING table caused the evil, repugnant database business logic to fire off some legacy code which updated the FOOBAR table.  Now, your cache says you have five FooBars, when in reality, you just inadvertently removed one.  </li>
<li>
<h4>Isolation Level and Performance</h4>
<p>	Part of administrating the Hibernate session involves tying it to a transaction manager.  	However, one thing to keep in mind is that the behavior of the session cache depends on the 	isolation level used in that underlying connection.  The more conservative the isolation level, the 	highest impact on performance since the chances and implications of locking become more prevalent.  </p>
<p>	For example, using an isolation level of serializable (which is default on some databases) 	prevents all database anomalies such as repeatable reads and phantom reads because it locks 	all tables within the transaction.  As a result, performance will be greatly impacted.  Using a less-	strict isolation level such as READ UNCOMMITTED will improve performance, but will in turn 	open up your database transactions to see uncommitted changes.  It is a difficult balance 	sometimes between performance and protection.</li>
<h3>SECOND LEVEL CACHE</h3>
<p>The second level cache has a more broad scope and is one that can greatly improve performance in applications.  It has a few differences. </p>
<ol>
<li>It can live across sessions</li>
<li>It can be distributed</li>
<li>It is not managed internally by Hibernate.  Instead, you have the ability to define a cache provider</li>
</ol>
<p>These points are all very important for one main reason:  because the data can now be distributed and can live across sessions, you have to be very careful about what is cached and how long that data stays cached.  Further, you now have to integrate another cache provider into Hibernate&#8217;s inner sanctum to help you do so.</p>
<p>So now we have data that is living across sessions.  Other servers, other users can all benefit from this cache rather than the selfish, session cache.  The problem is that by doing this, your sheltered world just got more complicated.  </p>
<p>The second level cache is also known as the object cache, but it doesn’t actually store the instances of the objects.  Instead it stores the values for the members of the object with an identifier as the key in the cache.  So, for example, let’s suppose we have the following table:</p>
<p><strong>TEACHER</strong></p>
<table border="1">
<tr>
<td>ID</td>
<td>NAME</td>
<td>SUBJECT</td>
</tr>
<tr>
<td>123</td>
<td>Mr. Garrison</td>
<td>English</td>
</tr>
<tr>
<td>456</td>
<td>Mr. Mackey</td>
<td>Math</td>
</tr>
</table>
<p>The second level cache will store cached data as:</p>
<p><code>{123, [Mr. Garrison, English]}<br />
{456, [Mr. Mackey, Math]}</code></p>
<p>So, asking for teacher 456 will simply use that ID to pull from the cache.  Now suppose we also have this table:</p>
<p><strong>STUDENT</strong></p>
<table border="1">
<tr>
<td>ID</td>
<td>NAME</td>
<td>TEACHER (FK)</td>
<td>GRADE</td>
</tr>
<tr>
<td>2009</td>
<td>Stan</td>
<td>123</td>
<td>5</td>
</tr>
<tr>
<td>2010</td>
<td>Kyle</td>
<td>456</td>
<td>5</td>
</tr>
<tr>
<td>2011</td>
<td>Eric</td>
<td>456</td>
<td>5</td>
</tr>
<tr>
<td>2012</td>
<td>Kenny</td>
<td>123</td>
<td>5</td>
</tr>
</table>
<p>Now, things get a bit more involved.  There is a one-to-many relationship now of teacher to student.  Your persistence-mapping file will most likely have three mappings to show this relationship:</p>
<ol>
<li>The Teacher class</li>
<li>The one-to-many relationship in the Teacher mapping to a set of Students, using Teacher ID as the key</li>
<li>The Student class</li>
</ol>
<p>Now, the reason I bring this up is related to my first item of interest for the second level cache:  </p>
<ul>
<li>
<h4>Caching Hibernate Associations</h4>
<p>	In the above scenario, you will have the ability to cache the Teacher mapping as well as the 	Teacher relationship to Student.  So, in that instance, two caches will be created to store the 	Teacher info as 	well as the IDs of the Students to which it’s related:</p>
<p><code>Teacher Cache<br />
	{123, [Mr. Garrison, English]}<br />
	{456, [Mr. Mackey, Math]}</code></p>
<p>	<code>Teacher.student Cache<br />
	{123, [2009, 2012]}<br />
	{456, [2010, 2011]}</code></p>
<p>	Ah, but here’s the rub.  Assuming the relationship between teacher and student is a typical fetch 	of ‘select’, you would expect then, that the following code would only run two queries: one for 	the teachers and one for the students and then only upon the first invocation of ‘load’.  </p>
<p><code>	Session.load(Teacher.class, 456);<br />
	Session.clear();<br />
	Session.load(Teacher.class, 456);</code></p>
<p>	Instead, it runs 3 queries:  two for the students and teachers in the first invocation and then one 	for the students in the second.  Adding another call to Session.load will run yet another query 	and so on.  </p>
<p>	This is because you also have to cache the Student mapping.  What the cache logic does is as follows:</li>
<ol>
<li>Check the Teacher cache.  If ID exists, get the info.</li>
<li>Check the Teacher.student cache.  If Teacher ID exists, get the Student IDs related to it</li>
<li>Retrieve the Students based on IDs</li>
</ol>
<p>	Since there is no Student cache,  a retrieval is done for Student info every time.  So, to cache 	associations, make sure you cache the parent class, the relationship, and the child class (even if 	the child class is never explicitly retrieved on its own)</p>
<li>
<h4>Not every Hibernate method invokes the cache</h4>
<p>One would think that any retrieval for an object would invoke the second-level cache.  One would think.  That is not the case, however.  It turns out that it’s specific to the method you are using to retrieve your data.  For example:</p>
<p><code>Session.load(Teacher.class, 456)<br />
Session.get(Teacher.class, 456)</code></p>
<p>Will both cause Hibernate to check the second level cache first for any existence of those IDs.  However doing something like the following will not:</p>
<p><code>Criteria crit = session.createCriteria(Teacher.class)<br />
crit.add(Restrictions.eq(“name”, “Mr. Garrison”);<br />
crit.list();</code></p>
<p>Because you are using a criteria object and querying for a list, Hibernate will not first check the second level cache for the existence of your objects.  OK, that sort of makes sense.  But what about these?</p>
<p><code>Crit.add(Restrictions.eq(“id”, 456L);<br />
Critieria.list();</code></p>
<p>OR </p>
<p><code>Crit.add(Restrictions.eq(“id”, 456L);<br />
Critieria.uniqueResult();</code></p>
<p>I am querying by the ID in both examples.  Plus, in the second one, I’m even asking for a unique result.  Will Hibernate at least check the cache on the second snippet?  Nope.  In both, though, the cache will be populated, which is important because this means more memory being utilized for no real purpose.	</li>
<p>	The takeaway here is that not only do certain methods not invoke the cache, but certain approaches to retrieval also do not.  More specifically, retrievals by a parameter other than the ID of the record will not check the second level cache.  This means that retrieving a codes table by the code name repeatedly will not get any better if you decide to cache it.  Since you are retrieving by name and not the designated ID, the second-level cache does not come into play.  Remember, in our teacher-student example, the keys in the cache were the IDs.  Likewise with the associations.<br />
So, how can we always guarantee a retrieval by ID so that we can make use of the second-level cache? Is there a way to dummy that up?  Glad you asked.  And don&#8217;t call me a dummy.</p>
<h3>QUERY CACHE</h3>
<p>The query cache is the third style of caching at your disposal.  Think of this one as Robin the Boy Wonder of caching.  By itself, it’s sort of useless.  However, with the second-level cache, it becomes a worthy companion and trusted sidekick.</p>
<p>What the query cache stores is basically a where clause and its bound parameters as a key, which is paired to the IDs that said where clause returns.  For example:</p>
<p><code>{[‘Where Teacher.Name = ?’, ‘Mr. Garrison’], 123}<br />
{[‘Where Teacher.Name = ?’, ‘Mr. Mackey], 456}  </code></p>
<p>As you can see, it is sort of useless by itself.  The query cache provides you means to an end.  It is a powerful complement to the second-level cache when IDs are not used for retrieval.<br />
The query cache also requires a high amount of analysis before just using willy-nilly.  There are many points to consider when making use of it.  <a href="http://tech.puredanger.com/2009/07/10/hibernate-query-cache/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://tech.puredanger.com/2009/07/10/hibernate-query-cache/');">Alex Miller wrote a great blog post on whether query caching is a good idea</a>.  So, check it out if you&#8217;re interested.  If not, I&#8217;ll sum up some points of his here as well as one I&#8217;ve come across in my experiences:</p>
<ul>
<li>
<h4>The query cache can get big</h4>
<p>Take a gander at the above example I wrote of the query cache.  Look at how verbose it looks already.  Now realize that this is my dopey scenario with ONE column in our where clause and one parameter.  Obviously, queries and where clauses can get to be enormous.  Query caching these behemoths will result in all that information just sitting around in memory.  So, while you&#8217;re making every effort to improve performance, you&#8217;re actually jamming a lot more into memory.  </li>
<li>
<h4>On frequently updated tables, the query cache is worthless</h4>
<p>	The query cache is managed by the caching provider through the use of a separate cache called the UpdateTimestampsCache.  The UpdateTimestampsCache maintains the last updated timestamp of particular tables.  When a table is updated or inserted, the last updated value is modified for that table in the timestamp cache.  Any entries in the query cache that correspond to that table are then invalidated.  Put simply, if the table you are caching in the query cache is updated or inserted FOR ANY REASON, your cache entry will become invalidated.  This means that updates or inserts completely unrelated to you or your data can still invalidate your entries.  </p>
<p>So, caching tables that are updating frequently in the system in the query cache is generally not a good idea.  The entries will become invalidated quite often, resulting in cache misses constantly. </li>
<li>
<h4>Query caching is ineffective on frequently changing parameters in Hibernate queries</h4>
<p>As you see in my example, the key to the query cache is composed of the where clause itself as well as the values of the bound parameters.  The astute programmer will realize that if either of these changes, we have a new entry in the cache.  In our example, the information is static, but suppose you have this:</p>
<p><code>{[‘Where Teacher.ModificationDate &lt; ?’, (some long representing a date)], 123}</code></p>
<p>Now suppose the query is invoked by passing in the current system time in milliseconds.  Since obviously the current time changes every (wait for it) millisecond, each repeated invocation of this query will result in a new parameter being passed in for Teacher.ModificationDate.  This means that there will be a cache miss each time this query is run, which will subsequently result in ANOTHER cache entry being created.  So, taking the first point about verbosity and this point into consideration, imagine an enormous where clause in which a constantly-changing parameter is passed in, such as the current time.  We will have unintended cache misses, resulting in unintended extraneous cache entries, which further results in an insane amount of data in memory.  </li>
<p>So, that is caching as far as my on-again, off-again love Hibernate is concerned.  The number one thing to take away from this post is to always consider the inherent implications.  On the surface, the three levels of caching that Hibernate provides are very powerful and are a useful way to improve performance.  But, deep down in the seedy underbelly lurk caveats at every turn.  Caching is not an easy process to manage or to even understand.  Just ask your grandmother.  And remember to eat the chicken soup.</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/k3ej4OzEwGM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/09/12/chicken-soup-for-the-caching-soul/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/09/12/chicken-soup-for-the-caching-soul/</feedburner:origLink></item>
		<item>
		<title>Five Oracle functions you might find useful</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/LWfKn5sG3gM/</link>
		<comments>http://www.summa-tech.com/blog/2011/09/06/five-oracle-functions-you-might-find-useful/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 18:18:24 +0000</pubDate>
		<dc:creator>Prem Nagrath</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[database]]></category>

		<category><![CDATA[Oracle]]></category>

		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3613</guid>
		<description><![CDATA[Most of an enterprise application developer’s exposure to the database is primarily restricted to basic <a href="http://en.wikipedia.org/wiki/Data_Definition_Language">DDL</a>, <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> operations and occasional SQL tuning. So when I recently got a chance to use some not-so-common Oracle functions/statements in a data-migration project, I thought they might be worth sharing. ]]></description>
			<content:encoded><![CDATA[<p>Most of an enterprise application developer’s exposure to the database is primarily restricted to basic <a href="http://en.wikipedia.org/wiki/Data_Definition_Language" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Data_Definition_Language');">DDL</a>, <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Create,_read,_update_and_delete');">CRUD</a> operations and occasional SQL tuning. So when I recently got a chance to use some not-so-common Oracle functions/statements in a data-migration project, I thought they might be worth sharing.  Here they are:</p>
<h3>1. Merge</h3>
<p>Also referred to as UPSERT, this Oracle PL/SQL statement can be used when it is not sure if you need to make an update or insert into the table. With <a href="http://psoug.org/reference/merge.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://psoug.org/reference/merge.html');">Merge</a> statement, you can insert into a table when the row does not exist or update it if it does. The syntax is:</p>
<pre name="code" class="sql:nocontrols:nogutter:nogutter">
MERGE <hint>
INTO
<table_name>
USING
<table_view_or_query>
ON ( <condition>)
WHEN MATCHED THEN <update>
WHEN NOT MATCHED THEN <insert>
</pre>
<p>So, the following Merge statement will add 1000 dollars to pending payment to the employee, if there is a payment already due for that employee in the Pending_Payments table. And if there is no payment due to the employee, it will create one for 1000 dollars for him/her.</p>
<pre name="code" class="sql:nocontrols:nogutter">
Merge into PENDING_PAYMENTS p
using (select employee_id from employee) e
on (e.employee_id = p.employee_id)
When Matched then
  update set p.payment_due = p.payment_due + 1000
When not matched
  then insert (p.employee_id, p.amount)
  values (e.employee_id, 1000);
</pre>
<h3>2. Delete multiple rows from a table that has a composite primary key</h3>
<p>This is a bit confusing and I will try my best to explain it with an example. Assume, you have two tables and you have to delete multiple rows from one of them using data from the other. So that is easy and the SQL statement would be:</p>
<pre name="code" class="sql:nocontrols:nogutter">
Delete from A
where id in (select a_id from B where <condition1>)
</pre>
<p>Now assume table A has a composite primary key and we have to achieve the same result. Would the following work?</p>
<pre name="code" class="sql:nocontrols:nogutter">
Delete from A where id_col1 in
  (select a_id_col1 from B where <condition1>)
and id_col2 in
  (select a_id_col2 from B where <condition1>)
</pre>
<p>No, but the desired result could be achieved with following statement:</p>
<pre name="code" class="sql:nocontrols:nogutter">
Delete from A where (id_col1, id_col2)
in (select a_id_col1, a_id_col2 from B where id in ( <condition1>))
</pre>
<h3>3. Minus Vs. “not in”</h3>
<p>Even though following statements give the same result, Oracle processes them differently:</p>
<pre name="code" class="sql:nocontrols:nogutter">
Select col1 from table1
minus select col1 from table2
select col1 from table1
where col1 not in (select col1 from table2)
</pre>
<p><a href="http://www.orafaq.com/wiki/Minus" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.orafaq.com/wiki/Minus');">Minus</a> does a full scan on both tables and removes the result from table2 from table1. “not in”, however, compares each row from table1 result with result from table2, resulting in far more reads than minus. So in most cases, it is preferred to use minus over “not in” for this performance reason.</p>
<h3>4. NVL</h3>
<p>The <a href="http://www.techonthenet.com/oracle/functions/nvl.php" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.techonthenet.com/oracle/functions/nvl.php');">NVL</a> function is used to substitute null values with a value. The following query would substiute a null middle_name with the literal ‘not available’ in the result rows:</p>
<pre name="code" class="sql:nocontrols:nogutter">
Select first_name,
  NVL(middle_name, ‘not availabale’),
  last_name from employee
</pre>
<h3>5. Decode</h3>
<p>The <a href="http://www.techonthenet.com/oracle/functions/decode.php" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.techonthenet.com/oracle/functions/decode.php');">decode</a> is like an “if-then-else” statement, and the syntax is:</p>
<pre name="code" class="sql:nocontrols:nogutter">
decode(expression, search, result [,search, result]….[,default])
</pre>
<p>So following statement would add an appropriate honorific while giving out the full names of all the employees.</p>
<pre name="code" class="sql:nocontrols:nogutter">
Select decode (gender, ‘M’, ‘Mr.’, ‘F’, ‘Ms.’)
  || ‘ ‘ || full_name from employee
</pre>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/LWfKn5sG3gM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/09/06/five-oracle-functions-you-might-find-useful/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/09/06/five-oracle-functions-you-might-find-useful/</feedburner:origLink></item>
		<item>
		<title>Setting Up Sequential IDs using JPA @TableGenerator</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/RgtnNUJcYfw/</link>
		<comments>http://www.summa-tech.com/blog/2011/07/29/setting-up-sequential-ids-using-jpa-tablegenerator/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 18:24:43 +0000</pubDate>
		<dc:creator>Mitch Goldstein</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[@GeneratedValue]]></category>

		<category><![CDATA[@Id]]></category>

		<category><![CDATA[@TableGenerator]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[jpa]]></category>

		<category><![CDATA[keys]]></category>

		<category><![CDATA[sequential]]></category>

		<category><![CDATA[unique]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3483</guid>
		<description><![CDATA[When using the Java Persistence Architecture (JPA) to perform object-relational mapping, it can become difficult to manage entities with complex keys.  Having a unique identifier is a keystone of the mapping approach, and complex keys can make coding awkward and difficult.  An alternative is to create entities with sequential unique numeric keys, and use the capabilities of the query facility to identify unique entities within the relational store.

JPA has several techniques to generate unique keys for entity objects.  This article focuses on one technique: using a database table to keep track of an incremental ID.  The <em><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html" target="_blank">@TableGenerator</a></em> annotation is used to facilitate this feature.]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>When using the Java Persistence Architecture (JPA) to perform object-relational mapping, it can become difficult to manage entities with complex keys.  Having a unique identifier is a keystone of the mapping approach, and complex keys can make coding awkward and difficult.  An alternative is to create entities with sequential unique numeric keys, and use the capabilities of the query facility to identify unique entities within the relational store.</p>
<p>JPA has several techniques to generate unique keys for entity objects.  This article focuses on one technique: using a database table to keep track of an incremental ID.  The <em><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html');" target="_blank">@TableGenerator</a></em> annotation is used to facilitate this feature.</p>
<h3>Database Setup</h3>
<p>In order to use <em><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html');" target="_blank">@TableGenerator</a></em>, we will need a database table that is accessible by JPA. Here is a sample script of how to create such a table in SQLServer:</p>
<pre>CREATE TABLE dbo.SEQUENCES (
	SEQ_NAME char(10) NOT NULL,
	SEQ_NUMBER int NOT NULL
) ON [PRIMARY]
GO</pre>
<p>This will create a table called dbo.SEQUENCES in your current database with two columns:</p>
<ul>
<li>The first column is a <em>sequence name </em>and can be used to manage multiple sequences within your object architecture.  In most cases, a single sequence can be used to create incremental unique keys for all entities.</li>
<li>The second column is the<em> sequence number</em> itself.  It is vitally important that this value not be externally editable or modified in any way.  If this value is changed, you might find yourself in a situation where you inadvertently re-use ID numbers, and this can wreak havoc in your code, especially if the generated ID is the primary key of your entity.</li>
</ul>
<p>You will need to insert at least one row into this table to make it useful.  We will assume a single generator will be used for all key values:</p>
<pre>INSERT INTO dbo.SEQUENCES (SEQ_NAME, SEQ_NUMBER)
        VALUES('SEQUENCE', 100)
GO</pre>
<p>This will create a sequence name of &#8216;SEQUENCE&#8217; with an initial value of 100.  The sequence name is used in the annotation to identify which value is to be used if there are multiple sequences being maintained.  Lastly, we will create a table to map a simple entity:</p>
<pre>CREATE TABLE dbo.EVENTS(
	[ID] int NOT NULL,
	[DESCRIPTION] varchar(200) NOT NULL,
        CONSTRAINT [PK_PRICING_EVENTS] PRIMARY KEY CLUSTERED
        ( [ID] ASC )    /* make ID the primary key */
) ON [PRIMARY]
GO</pre>
<h3>Creating the Mapping</h3>
<p>Now we can create our mapping in our Java class.  We will create an entity mapping and use field mapping for it&#8217;s two properties.  The first one will be mapped as the unique ID and the second as the value of the DESCRIPTION column in the table we have created.</p>
<pre>@Entity
@Table(name = "EVENTS")
public class SequentialEvent implements Serializable
{
    private static final long serialVersionUID = 3107897896655094094L;

     @Id
     @TableGenerator(name = "EVENT_GEN",
                table = "SEQUENCES",
		pkColumnName = "SEQ_NAME",
                valueColumnName = "SEQ_NUMBER",
		pkColumnValue = "SEQUENCE",
                allocationSize=1)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "EVENT_GEN")
    @Column(name = "ID")
    protected int _id;
    @Column(name = "DESCRIPTION")
    protected String _description;

    // REMAINDER OF CLASS OMITTED
}</pre>
<p>Here is an explanation of the annotations in this class:</p>
<ul>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/Entity.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/Entity.html');" target="_blank">@Entity</a></strong> - marks this class as a JPA persistable entity</li>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/Table.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/Table.html');" target="_blank">@Table</a> </strong>- denotes the name of the table in which this entity is stored</li>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/Id.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/Id.html');" target="_blank">@Id</a></strong> - declares the field it refers to as the unique identifier for this entity</li>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html');" target="_blank">@TableGenerator</a></strong> - informs JPA how to generate unique values for this entity&#8217;s identifier.  It has several parameters:
<ul>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#name%28%29" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#name%28%29');" target="_blank">name</a> </strong>- identifier for the generator binding.  This value must match the parameter in the @GeneratedValue annotation as described below.</li>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#table%28%29" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#table%28%29');" target="_blank">table</a> </strong>- must match the name of the table created to store the sequence values.</li>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#pkColumnName%28%29" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#pkColumnName%28%29');" target="_blank">pkColumnName</a> </strong>- the primary key <em>column name</em> that contains the name of the sequence we are using.</li>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#valueColumnName%28%29" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#valueColumnName%28%29');" target="_blank">valueColumnName</a> </strong>- the name of the column that contains the numeric sequence value</li>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#pkColumnValue%28%29" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#pkColumnValue%28%29');" target="_blank">pkColumnValue</a> </strong>- the <em>value </em>of the primary key column that identifies the sequence</li>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#allocationSize%28%29" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html#allocationSize%28%29');" target="_blank">allocationSize</a> </strong>- the amount by which this sequence should be incremented each time a new entity is created.  The default value for this is fifty (50).</li>
</ul>
</li>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/GeneratedValue.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/GeneratedValue.html');" target="_blank">@GeneratedValue</a></strong> - marks the field as having a generated value, either from the database or from some other ID generation strategy.  This has two important parameters:
<ul>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/GeneratedValue.html#strategy%28%29" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/GeneratedValue.html#strategy%28%29');" target="_blank">strategy</a> </strong>- a value from the <em><a href="http://download.oracle.com/javaee/5/api/javax/persistence/GenerationType.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/GenerationType.html');" target="_blank">GenerationType</a></em> enumeration that declares the the way in which values will be generated.  In this example <a href="http://download.oracle.com/javaee/5/api/javax/persistence/GenerationType.html#TABLE" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/GenerationType.html#TABLE');" target="_blank"><em>GenerationType.TABLE</em></a> is appropriate since we are letting the value be managed in the relational store.</li>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/GeneratedValue.html#generator%28%29" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/GeneratedValue.html#generator%28%29');" target="_blank">generator</a></strong>- must match the name of the <em><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html');" target="_blank">@TableGenerator</a></em> tag to provide the specifics on how the value is to be generated.</li>
</ul>
</li>
<li><strong><a href="http://download.oracle.com/javaee/5/api/javax/persistence/Column.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/Column.html');" target="_blank">@Column</a></strong> - declares the field to be mapped to a database column.</li>
</ul>
<p>It is important to note that when employing this particular strategy, the ID of the entity that you are creating will be undefined until the object is persisted.  This must be a consideration when determining how to architect your application code.</p>
<p>For more information on <em><a href="http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/TableGenerator.html');" target="_blank">@TableGenerator</a></em> and other key generation techniques, please refer to <a href="http://download.oracle.com/javaee/5/api/javax/persistence/package-summary.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/package-summary.html');" target="_blank">JPA documentation</a>.</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/RgtnNUJcYfw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/07/29/setting-up-sequential-ids-using-jpa-tablegenerator/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/07/29/setting-up-sequential-ids-using-jpa-tablegenerator/</feedburner:origLink></item>
		<item>
		<title>Modeling Reference Data in the Application Tier</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/DcZGgarbZhk/</link>
		<comments>http://www.summa-tech.com/blog/2011/07/25/reference-data-in-the-application-tier/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 17:34:19 +0000</pubDate>
		<dc:creator>Ben Northrop</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[object oriented]]></category>

		<category><![CDATA[OO design]]></category>

		<category><![CDATA[patterns]]></category>

		<category><![CDATA[reference data]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3497</guid>
		<description><![CDATA[In every enterprise application, there exists <a href="	http://www.information-management.com/issues/20060401/1051002-1.html?pg=2 
">reference data</a> - those simple entities that live on the periphery of your data model, and are used to classify your <a href="http://en.wikipedia.org/wiki/Master_data">master data</a>.  We often know these entities by other names (depending on our point of view), for instance "lookup tables", "configuration data", etc. - examples being "State", "CustomerType", or "ProductType".  

Now there are some <a href="http://www.projectdmx.com/dbdesign/lookup.aspx">strong reasons</a> to model these entities in separate tables in your relational database, and there is generally not much debate here.  Where things get a little tricky is when this reference data propagates up into the application tier.  In my experience, developers employ a number of different strategies to solve this problem, and so in this post I'll define some of the more popular approaches and describe the pros and cons of each.  As always, I'd love to hear your thoughts, so please share.  Here goes...]]></description>
			<content:encoded><![CDATA[<p>In every enterprise application, there exists <a href="	http://www.information-management.com/issues/20060401/1051002-1.html?pg=2<br />
" onclick="javascript:pageTracker._trackPageview('/outbound/article/	http://www.information-management.com/issues/20060401/1051002-1.html?pg=2<br />
');">reference data</a> - those simple entities that live on the periphery of your data model, and are used to classify your <a href="http://en.wikipedia.org/wiki/Master_data" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Master_data');">master data</a>.  We often know these entities by other names (depending on our point of view), for instance &#8220;lookup tables&#8221;, &#8220;configuration data&#8221;, etc. - examples being &#8220;State&#8221;, &#8220;CustomerType&#8221;, or &#8220;ProductType&#8221;.  </p>
<p>Now there are some <a href="http://www.projectdmx.com/dbdesign/lookup.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.projectdmx.com/dbdesign/lookup.aspx');">strong reasons</a> to model these entities in separate tables in your relational database, and there is generally not much debate here.  Where things get a little tricky is when this reference data propagates up into the application tier.  In my experience, developers employ a number of different strategies to solve this problem, and so in this post I&#8217;ll define some of the more popular approaches and describe the pros and cons of each.  As always, I&#8217;d love to hear your thoughts, so please share.  Here goes&#8230;</p>
<h3>Types of Reference Data</h3>
<p>Let&#8217;s first start with an example.  Imagine your system has customers, and every customer has some loyalty level (e.g. &#8220;Gold&#8221;, &#8220;Silver&#8221;, etc.&#8221;).  The tables could be designed simply as follows:</p>
<p><br/></p>
<div align="center">
<a href="http://www.summa-tech.com/blog/2011/07/25/reference-data-in-the-application-tier/reference-data-erd1/"  rel="attachment wp-att-3506"><img src="http://www.summa-tech.com/blog/wp-content/uploads/2011/07/reference-data-erd1.gif" alt="reference-data-erd1" title="reference-data-erd1" width="406" height="58" class="aligncenter size-full wp-image-3506" /></a>
</div>
<p><br/></p>
<p>&#8230;and the data in the LOYALTY_LEVEL table might be&#8230;</p>
<p><br/></p>
<style>
  .customTable TD {  border-style: solid; border-width: 1px; border-color: #999999;  margin: 0px; padding: 3px; }
</style>
<table class="customTable" align="center" width="200"  border="0" >
<tr>
<td><b>id</b></td>
<td><b>name</b></td>
</tr>
<tr>
<td>G</td>
<td>Gold</td>
</tr>
<tr>
<td>S</td>
<td>Silver</td>
</tr>
<tr>
<td>B</td>
<td>Bronze</td>
</tr>
</table>
<p><br/></p>
<p>This is a pretty vanilla example, so it would be tempting to jump right in and translate this into the application tier, but before we do it&#8217;s important to stop and  ask a few questions first:</p>
<style>
  .customList LI { margin: 6px 0px 6px 0px; }
</style>
<ol class="customList">
<li>Does the reference data need to be retrieved <b>independent</b> of the master data (e.g. display all loyalty levels in a drop-down, etc.)?</li>
<li>Are there <b>other attributes</b> beyond just the normal id-name pair?  For example, &#8220;description&#8221;, &#8220;abbreviation&#8221;, or something with more business meaning like &#8220;percentage discount&#8221;, etc.?</li>
<li>Do specific values need to be hard-coded into the <b>business logic</b>?   For example, could there be logic <code>if (cust.loyaltyLevel == "Gold") { sendOvernightMail() } </code> &#8230;or something similar?</li>
<li>Is the reference data at all <b>dynamic</b>?  For example, could there be a new loyalty level at some point (e.g. &#8220;Diamond&#8221; or maybe &#8220;Coal&#8221;!)?  Further, is this reference data <i>very</i> dynamic in that it could be added by a user via some UI, or would a new value be a configuration change?</li>
</ol>
<p>Now I can hear the objections already: &#8220;hey, not all of these types of &#8216;reference data&#8217; are really reference data!&#8221;.  And that&#8217;s actually the point.  Oftentimes, in my experience, we fail to appreciate these four distinctions, and we shoe-horn all  entities that even roughly resemble reference data into the same solution, to sometimes pernicious consequences.  For example, we may treat States the same as Loyalty Levels in the application tier, even though the former is probably static, not used in business logic, and will only ever have two-attributes, while the latter could be the exact opposite.  </p>
<p>To best understand how to design for different types of reference data, it&#8217;s helpful to lay out a few common solutions&#8230; </p>
<h3>1. Flatten in Model Class</h3>
<p>An unsophisticated (but not uncommon) approach is to flatten the reference data in the containing model object.  For example, the customer class could look like this:</p>
<pre name="code" class="java:nocontrols">
  public class Customer {
    private String name;
    private String loyaltyCode;
    private String loyaltyName;  // optional
  }
</pre>
<p>Obviously this will work, until a new attribute needs to be added to a Loyalty Level (e.g. &#8220;description&#8221;)&#8230;or Loyalty Codes need to be retrieved independent of Customers (e.g. to populate some drop-down), in which case you&#8217;ll probably want to define a&#8230;</p>
<h3>2. Custom Class</h3>
<p>A custom LoyaltyLevel class could be created with the two attributes &#8220;code&#8221; and &#8220;name&#8221;&#8230;</p>
<pre name="code" class="java:nocontrols">
  public class LoyaltyLevel {
    private String code;
    private String name;
  }
</pre>
<p>&#8230;and then composed within the Customer class:</p>
<pre name="code" class="java:nocontrols">
  public class Customer {
    private String name;
    private LoyaltyLevel level;
  }
</pre>
<p>On the up side, the LoyaltyLevel class could be fetched independent of Customers (e.g. to populate a drop-down, etc.), and attributes could easily be added to the LoyaltyLevel class without adding unnecessary bloat to the Customer class.  </p>
<p>The problem comes when you want to create some business logic that refers to some specific loyalty level.  Using the example above, it&#8217;s possible that some business rule should be written such that customers at the &#8220;Gold&#8221; level are treated in special manner.</p>
<pre name="code" class="java:nocontrols">
  if("G".equals(customer.getLoyaltyLevel().getCode())) {
    sendOvernightMail();
  }
  else {
    sendViaHorseAndBuggy();
  }
</pre>
<p>Again, this works, but there are a few problems.  First, the &#8220;code&#8221; attribute in LoyaltyLevel is not type-safe, since it&#8217;s just a String in the LoyaltyLevel class, and so there&#8217;s not guarantee that an invalid value (e.g. &#8220;X&#8221;) couldn&#8217;t creep in.  Second, we&#8217;re hard-coding the level, &#8220;G&#8221;, into our business logic, and while this could be ameliorated with a simple String constant, again, this is not type-safe (and a general <a href="http://www.odi.ch/prog/design/newbies.php#40" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.odi.ch/prog/design/newbies.php#40');">anti-pattern</a>).  And finally, it&#8217;s very easy to forget to write bugs where &#8220;G&#8221; is compared with the LoyaltyLevel object itself and not it&#8217;s String code.  For example:</p>
<pre name="code" class="java:nocontrols">
  if("G".equals(customer.getLoyaltyLevel()) { // forgot .getCode()!
    sendOvernightMail()
  }
</pre>
<p>In other words, if specific LoyaltyLevels are to be used in the business logic, it&#8217;s much preferable to keep them typesafe in an&#8230;</p>
<h3>3. Enum </h3>
<p>A LoyaltyLevel enum could be created in the application tier:</p>
<pre name="code" class="java:nocontrols">
  public enum LoyaltyLevel {
    Gold("G", "Gold"),
    Silver("S", "Silver"),
    Bronze("B", "Bronze");

    ...
  }
</pre>
<p>&#8230;and a type handler construct in your ORM tool (like <a href="http://weblog.dangertree.net/2007/09/23/mapping-java-5-enums-with-hibernate/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://weblog.dangertree.net/2007/09/23/mapping-java-5-enums-with-hibernate/');">Hibernate&#8217;s</a> or <a href="http://www.google.com/url?sa=t&#038;source=web&#038;cd=2&#038;ved=0CCAQFjAB&#038;url=http%3A%2F%2Fibatis.apache.org%2Fdocs%2Fjava%2Fuser%2Fcom%2Fibatis%2Fsqlmap%2Fclient%2Fextensions%2FTypeHandlerCallback.html&#038;ei=opIpToy2O4TAtgea4qDXAg&#038;usg=AFQjCNHaijd_54pjsYM3LisX06KJGEzpXA" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.google.com/url?sa=t&#038;source=web&#038;cd=2&#038;ved=0CCAQFjAB&#038;url=http%3A%2F%2Fibatis.apache.org%2Fdocs%2Fjava%2Fuser%2Fcom%2Fibatis%2Fsqlmap%2Fclient%2Fextensions%2FTypeHandlerCallback.html&#038;ei=opIpToy2O4TAtgea4qDXAg&#038;usg=AFQjCNHaijd_54pjsYM3LisX06KJGEzpXA');">IBatis</a>, etc.) can be used to easily load this into the Customer object on retrieval from the database:</p>
<pre name="code" class="java:nocontrols">
  public class Customer {
    private String name;
    private LoyaltyLevel level;
  }
</pre>
<p>Voila! This solves our problems, right?  LoyaltyLevels can be retrieved independent of Customers, new attributes can be easily added without affecting the master data, and specific instances can be easily (and type-safely) referred to in business logic (e.g. &#8220;LoyaltyLevel.Gold == cust.getLoyaltyLevel()&#8221;).</p>
<p>Not so fast!  What happens when the business wants to add a &#8220;Diamond&#8221; level?  Or wants to get rid of their &#8220;Bronze&#8221; level and replace it with an &#8220;Aluminum&#8221;?  In either case, both the enum <i>and</i> the database need to change (since both redundantly define the Loyalty Levels), which obviously necessitates a code/configuration change (i.e. not something that could happen via some UI).  In cases where the reference data is very static, this may be fine, but if Loyalty Levels are to be added with any fluidity, encapsulating the different values in Enums won&#8217;t work.</p>
<h3>Analysis and Recommendations</h3>
<p>So I&#8217;ve presented 3 solutions, and as the table below shows, each solution has its drawbacks.  Things are less clear now than before!  What gives?</p>
<p><br/></p>
<style>
  .bad { color: red; font-weight: bold;  }
  .good { color: green; font-weight: bold; }
</style>
<table class="customTable" align="center" border="0" >
<tr>
<td><b></b></td>
<td><b>Independent?</b></td>
<td><b>+2 Attributes?</b></td>
<td><b>Business Logic?</b></td>
<td><b>Dynamic?</b></td>
</tr>
<tr>
<td><b>1. Flatten in Model Class</b></td>
<td class="bad">Bad</td>
<td class="bad">Bad</td>
<td class="bad">Bad</td>
<td class="good">Good</td>
</tr>
<tr>
<td><b>2. Custom Class</b></td>
<td class="good">Good</td>
<td class="good">Good</td>
<td class="bad">Bad</td>
<td class="good">Good</td>
</tr>
<tr>
<td><b>3. Enum</b></td>
<td class="good">Good</td>
<td class="bad">Bad</td>
<td class="good">Good</td>
<td class="bad">Bad</td>
</tr>
</table>
<p><br/></p>
<p>In the end, is there an good answer?  Well, I&#8217;ve found the following two heuristics to be helpful:</p>
<p>1. If the reference data is static, has few attributes, and is used in business logic, use an <b>Enum</b>.  The redundancy of reference data defined both in both an enum and a table in the database is relatively harmless (since the data is static!), and worth the cost for gaining the benefit of type safety, clarity, and ease of use (in my opinion).  </p>
<p>2. In all other cases, use a <b>Custom Class</b>.  In cases where the business logic seems to reference a specific value, rather than hard-code (e.g. &#8220;G&#8221;.equals(code)), try to refactor this such that the data makes the decision rather than the code.  For example, in the example of Loyalty Levels and shipping methods, a new column added to the Loyalty Level table&#8230;</p>
<table class="customTable" align="center" width="300"  border="0" >
<tr>
<td><b>id</b></td>
<td><b>name</b></td>
<td><b>ship_overnight</b></td>
</tr>
<tr>
<td>G</td>
<td>Gold</td>
<td>true</td>
</tr>
<tr>
<td>S</td>
<td>Silver</td>
<td>false</td>
</tr>
<tr>
<td>B</td>
<td>Bronze</td>
<td>false</td>
</tr>
</table>
<p>&#8230;and this would effectively eliminate the dependency on a specific reference data value in the code and move it to the database.</p>
<p>3. If you absolutely need to hard-code the &#8220;code&#8221; values of the reference data for business logic, then do so with <b>constants</b> in one place and as close to the reference data class as possible (preferably in it).  Do not sprinkle hard-coded values (e.g. &#8220;G&#8221;, &#8220;S&#8221;, etc.) around your business logic.  (I know&#8230;duh!)</p>
<p>Anyway, I&#8217;d love to hear your thoughts.  Am I missing something?  How do you manage reference data in the application tier?</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/DcZGgarbZhk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/07/25/reference-data-in-the-application-tier/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/07/25/reference-data-in-the-application-tier/</feedburner:origLink></item>
		<item>
		<title>Mvp4g multiple presenters - Part 3</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/XVxY8xz_av4/</link>
		<comments>http://www.summa-tech.com/blog/2011/06/29/mvp4g-multiple-presenters-part-3/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 16:58:16 +0000</pubDate>
		<dc:creator>Javier Ochoa</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[GWT]]></category>

		<category><![CDATA[mvp4g]]></category>

		<category><![CDATA[RIA]]></category>

		<category><![CDATA[user interface]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3449</guid>
		<description><![CDATA[This is the third in the Mvp4g Multiple Presenters series (<a href="http://www.summa-tech.com/blog/2011/04/27/mvp4g-multiple-presenters-part-1/">part 1</a> and <a href="http://www.summa-tech.com/blog/2011/05/11/mvp4g-multiple-presenters-part-2/">part 2</a>). In this post I will demonstrate how to use the <a href="http://blog.jdevelop.eu/2010/01/17/use-generators-to-create-boilerplate-code-in-gwt-20/">GWT generator</a> to differentiate events that are to be filtered by an event group. This gives you more freedom when defining your events and gets rid of the "$" that we used to define the event name. Plus in this post I will also remove the presenter registry and enhance the event filtering by overriding the isActivated() method. ]]></description>
			<content:encoded><![CDATA[<div class="seriesmeta">This entry is part 9 of 9 in the series <a href="http://www.summa-tech.com/blog/series/developing-gwt-applications/"  title="series-272">Developing GWT Applications</a></div><p>This is the third in the Mvp4g Multiple Presenters series (<a href="http://www.summa-tech.com/blog/2011/04/27/mvp4g-multiple-presenters-part-1/" >part 1</a> and <a href="http://www.summa-tech.com/blog/2011/05/11/mvp4g-multiple-presenters-part-2/" >part 2</a>). In this post I will demonstrate how to use the <a href="http://blog.jdevelop.eu/2010/01/17/use-generators-to-create-boilerplate-code-in-gwt-20/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://blog.jdevelop.eu/2010/01/17/use-generators-to-create-boilerplate-code-in-gwt-20/');">GWT generator</a> to differentiate events that are to be filtered by an event group. This gives you more freedom when defining your events and gets rid of the &#8220;$&#8221; that we used to define the event name. Plus in this post I will also remove the presenter registry and enhance the event filtering by overriding the isActivated() method. </p>
<p>So here are the steps I&#8217;ll be following:</p>
<ol>
<li>Split the event bus interface by moving the event group methods to a different compile unit: GroupEventBus.</li>
<li>Define the GWT generator which will read and add the methods defined in the GroupEventBus interface to create the list of group events.</li>
<li>Remove the event registry from PresenterHandler and override the isActivated method to filter the event for specific presenters.</li>
</ol>
<h3>Split EventBus interface</h3>
<p>All we need to do is move the &#8220;setSelectedItem$&#8221; method from MultiPresentersEventBus to a new interface GroupEventBus:</p>
<pre name="code" class="java:nocontrols">
public interface GroupEventBus {
	@Event(handlers = ReceiverPresenter.class)
	void setSelectedItem(String group, String value);
}
</pre>
<p>And have MultiPresentersEventBus extend GroupEventBus to include the methods as events in our event bus:</p>
<pre name="code" class="java:nocontrols">
public interface MultiPresentersEventBus extends EventBus, GroupEventBus {
...
}
</pre>
<h3>Write GWT generator</h3>
<p>Reflection does not exist in Javascript, but the way to overcome this in GWT is by using <a href="http://blog.jdevelop.eu/2010/01/17/use-generators-to-create-boilerplate-code-in-gwt-20/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://blog.jdevelop.eu/2010/01/17/use-generators-to-create-boilerplate-code-in-gwt-20/');">Generators</a>. My goal here is to have a new class that extends List<String> and will contain a simple constructor with a list of &#8220;add(&#8221;xyz&#8221;);&#8221; calls for each and every event found in the new GroupEventBus.  Make sense?</p>
<p>a. Ok, first we write an empty marker interface that we later can call GWT.create on.</p>
<pre name="code" class="java:nocontrols">
public interface GroupEventList extends List&lt;String&gt;{
}
</pre>
<p>b. Next we write the generator class that extends Generator and carefully generates every single line needed to create GroupEventListImpl class. To keep my post short look <a href="http://code.google.com/p/gwt-summa-tech/source/browse/src/main/java/com/summatech/gwt/mvp/server/util/GroupEventListGenerator.java?repo=mvp" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://code.google.com/p/gwt-summa-tech/source/browse/src/main/java/com/summatech/gwt/mvp/server/util/GroupEventListGenerator.java?repo=mvp');">here</a> for the source.</p>
<p>c. Now in our GWT module we specify that this Generator is used to get the implementation of GroupEventList.</p>
<pre name="code" class="java:nocontrols">
&lt;generate-with class=&quot;com.summatech.gwt.mvp.server.util.GroupEventListGenerator&quot;&gt;
  &lt;when-type-assignable class=&quot;com.summatech.gwt.mvp.client.GroupEventList&quot; /&gt;
&lt;/generate-with&gt;
</pre>
<p>d. And as last point rework our MultiPresentersEventFilter to instantiate our newly created class and get a hold on the Group Event List.</p>
<pre name="code" class="java:nocontrols">
    /** Get the list of grouped events from the generated GroupEventList class */
    private List&lt;String&gt; groupedEvents = GWT.create(GroupEventList.class);
</pre>
<p>  and re-write our logic in the event filter to use this list:</p>
<pre name="code" class="java:nocontrols">
public boolean filterEvent(String eventName, Object[] params, MultiPresentersEventBus eventBus) {
  // Deactivate presenters registered for a group in the list
  if (groupedEvents.contains(eventName)) {
    presenterHandler.activateGroup((String) params[0]);
  }
  return true;
}
</pre>
<h3>Remove presenter registry using isActivated method</h3>
<p>And the last change to our project is to get rid of our Map of presenters created in the PresenterHandler singleton. Instead we use a method from <a href="http://code.google.com/p/mvp4g/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://code.google.com/p/mvp4g/');">Mvp4g</a> which gets called on every event triggered to find out if the presenter is active and if so forward the event. This method returns a boolean, and all we need to do is overwrite it and check whether the presenter is in the &#8220;active&#8221; event group.</p>
<p>First we get rid of the map registry in Presenter handler and modify the activateGroup method to simply register the current active group and its public getter:</p>
<pre name="code" class="java:nocontrols">
public void activateGroup(String groupToActivate) {
    this.activeEventGroup=groupToActivate;
}

public String getActiveEventGroup(){
    return activeEventGroup;
}
</pre>
<p>Now we go back to the AbstractGroupPresenter from which our multiple presenters are extending and override the isActivated method as this:</p>
<pre name="code" class="java:nocontrols">
@Override
public boolean isActivated(boolean passive) {
  if (group!=null &#038;&#038; !group.equals("")) {
    return group.equals(presenterHandler.getActiveEventGroup()) &#038;&#038; super.isActivated(passive);
  } else {
    return super.isActivated(passive);
  }
}
</pre>
<p>  and use Guice to inject the PresenterHandler singleton:</p>
<pre name="code" class="java:nocontrols">
  @Inject
  PresenterHandler presenterHandler;
</pre>
<p>And this is it. The same magic as in the previous post still happens but with cleaner and more optimized code. Neat, isn&#8217;t it? I really think this is a good use of the GWT generator and a good way of using Mvp4g to accomodate this use case of multiple presenters.</p>
<p>Now, in Mvp4g 1.4.0 I believe will have the isActivated method with the event name and event parameters in which case you can now think of a different way to access the triggered event group and get rid of the Event Filter altogether. That might be subject for an extra post in this series if time and energy permits.</p>
<p>I migrated my code to this <a href="http://code.google.com/p/gwt-summa-tech/source/browse/?repo=mvp" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://code.google.com/p/gwt-summa-tech/source/browse/?repo=mvp');">new repository</a>, feel free to check it out and play with it.</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/XVxY8xz_av4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/06/29/mvp4g-multiple-presenters-part-3/feed/</wfw:commentRss>
	
		<series:name><![CDATA[Developing GWT Applications]]></series:name>
	<feedburner:origLink>http://www.summa-tech.com/blog/2011/06/29/mvp4g-multiple-presenters-part-3/</feedburner:origLink></item>
		<item>
		<title>Tweaking Persistence with @PrePersist</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/fQfBj_Gpzek/</link>
		<comments>http://www.summa-tech.com/blog/2011/06/13/tweaking-persistence-with-prepersist/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 14:00:06 +0000</pubDate>
		<dc:creator>Mitch Goldstein</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[@PrePersist]]></category>

		<category><![CDATA[BigDecimal]]></category>

		<category><![CDATA[hibernate]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[jpa]]></category>

		<category><![CDATA[persistence]]></category>

		<category><![CDATA[rounding]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3433</guid>
		<description><![CDATA[It is an interesting problem: even though the Java primitive <em>double</em> type has plenty of precision, math operations using this type can prove problematic when it comes to using them for precision calculations.  Due to the nature of how floating point numbers are stored, they are by definition inaccurate.  This is a consequence of trying to store decimals - especially fractional decimals - in a binary format.

To address some of these issues, the Java development team released the <a href="http://download.oracle.com/javase/6/docs/api/java/math/BigDecimal.html"><em>java.math.BigDecimal</em></a> class.  This is an immutable class that extends the abstract class <a href="http://download.oracle.com/javase/6/docs/api/java/lang/Number.html"><em>java.lang.Number</em></a>, which serves as the superclass of  the primitive wrapper classes such as<a href="http://download.oracle.com/javase/6/docs/api/java/lang/Double.html"> <em>java.lang.Double</em></a> and <a href="http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html"><em>java.lang.Integer</em></a>.  The primary purpose of this base class is to provide methods that allow conversion among different number types.
]]></description>
			<content:encoded><![CDATA[<p>It is an interesting problem: even though the Java primitive <em>double</em> type has plenty of precision, math operations using this type can prove problematic when it comes to using them for precision calculations.  Due to the nature of how floating point numbers are stored, they are by definition inaccurate.  This is a consequence of trying to store decimals - especially fractional decimals - in a binary format.</p>
<p>To address some of these issues, the Java development team released the <a href="http://download.oracle.com/javase/6/docs/api/java/math/BigDecimal.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javase/6/docs/api/java/math/BigDecimal.html');"><em>java.math.BigDecimal</em></a> class.  This is an immutable class that extends the abstract class <a href="http://download.oracle.com/javase/6/docs/api/java/lang/Number.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javase/6/docs/api/java/lang/Number.html');"><em>java.lang.Number</em></a>, which serves as the superclass of  the primitive wrapper classes such as<a href="http://download.oracle.com/javase/6/docs/api/java/lang/Double.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javase/6/docs/api/java/lang/Double.html');"> <em>java.lang.Double</em></a> and <a href="http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html');"><em>java.lang.Integer</em></a>.  The primary purpose of this base class is to provide methods that allow conversion among different number types.</p>
<p><em>BigDecimal</em> is supported by the <a href="http://download.oracle.com/javaee/6/api/javax/persistence/package-summary.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/6/api/javax/persistence/package-summary.html');">Java Persistence API (JPA)</a>, which uses <a href="http://download.oracle.com/javase/1.5.0/docs/guide/language/annotations.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javase/1.5.0/docs/guide/language/annotations.html');">Java Annotations</a> to integrate Java objects with relational entities.  This makes <em>BigDecimal</em> very tempting to use in lieu of<em> </em>floating-point primitives, since the JPA code, in conjunction with the <a href="http://en.wikipedia.org/wiki/Java_Database_Connectivity" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Java_Database_Connectivity');">JDBC driver</a>, automatically converts persisted numeric values to <em>BigDecimal</em> when they are mapped to numeric table columns.  However, this can be problematic depending on the type of database you happen to be connecting to.</p>
<h3>The Problem</h3>
<p>I encountered a problem where an object I wanted to persist was throwing a JDBC exception.  It turned out that the problem was caused by the way the JDBC driver handles <em>BigDecimal </em>properties. This code illustrates this peculiarity:</p>
<p><code>BigDecimal bd = new BigDecimal(48.28);<br />
System.out.println("toString()    = " + bd.toString());<br />
System.out.println("doubleValue() = " + bd.doubleValue());<br />
</code></p>
<pre><strong>Output:
toString()    = 48.280000000000001136868377216160297393798828125
doubleValue() = 48.28</strong></pre>
<p>Was this what you might have expected?  It looks like the interpretation of the value is correct, but the string representation seems to have several decimal places of precision followed by random junk!  Little did I know that this would wreak havoc in my code.  Apparently, my JDBC driver converts the value to a string, which can usually, but not always, be digested.  I would get a sporadic exception such as this when I tried to persist this data:</p>
<pre>JDBCExceptionReporter:234 - Error converting data type nvarchar to decimal.</pre>
<p>So what is the problem?  Here we have a monetary value with two decimal places of precision.  We want to use <em>BigDecimal</em> to eliminate rounding errors, and we can&#8217;t get it into the database?</p>
<h3>The Solution</h3>
<p>Regrettably, we don&#8217;t have control over the internal workings of JPA or the associated JDBC drivers, so we have to work with what we have.  What we really need to do is to figure out how to modify the precision of the <em><a href="http://download.oracle.com/javase/1,5.0/docs/api/java/math/BigDecimal.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javase/1,5.0/docs/api/java/math/BigDecimal.html');">BigDecimal</a> </em>so it still behaves the way we want, but doesn&#8217;t cause the code in the driver to break.</p>
<p>Since <em>BigDecimal </em>is  immutable, we really can&#8217;t fiddle with the values themselves.  Much like the analogous <em>String</em> class, operations which alter values all return a fresh <em>String </em>object with the desired changes.  There are operations that can be used to adjust the scale of the <em>BigDecimal</em> so that its raw string representation is not quite so cumbersome.<br />
<code>BigDecimal bd = new BigDecimal(48.28);<br />
bd = bd.setScale(10, RoundingMode.HALF_EVEN);<br />
System.out.println("toString()    = " + bd.toString());<br />
System.out.println("doubleValue() = " + bd.doubleValue());<br />
</code></p>
<pre>Output:
toString()    = 48.2800000000
doubleValue() = 48.28</pre>
<p>Even so - if you are using JPA to it&#8217;s fullest extent, it is quite likely that your mappings are applied not to your class&#8217;s methods, but directly to a class field, such as this declaration:<br />
<code>@Column (name = "PRICE")<br />
protected BigDecimal _price;</code><br />
This basically means you cannot &#8216;trap&#8217; the update of this field in a method call when JPA uses reflection to update this value - how can we ensure our values are persistable if we can&#8217;t interrupt the persistance process?</p>
<h3>The @PrePersist Annotation</h3>
<p>The developers of JPA anticipated this issue and provided a very useful way to invoke code when an object is just about to be persisted.  Using reflection, the persistence engine will look for any methods within the entity that is annotated with the <em><a href="http://download.oracle.com/javaee/5/api/javax/persistence/PrePersist.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javaee/5/api/javax/persistence/PrePersist.html');">@PrePersist</a> </em>annotation.  This provides an excellent hook to either examine or modify entity values before they are persisted by JPA.  In the case of the &#8216;price&#8217; field above, we could add a method to tweak the value of the price to a more reasonable value before we try to insert the value in a table.</p>
<pre>    @PrePersist
    protected void prePersist()
    {
        _price = _price.setScale(10, RoundingMode.HALF_EVEN);
    }</pre>
<p>This method will get invoked just prior to our object getting persisted, and will replace the &#8216;price&#8217; value with its equivalent value, adjusting it&#8217;s scale so that it is still very precise, but will not cause problems due to string length when it is persisted to a relational store.</p>
<p>The second parameter of the <em>setScale() </em>method gives the rounding strategy that is used for the conversion.  Any time the scale of a <em><a href="http://download.oracle.com/javase/1,5.0/docs/api/java/math/BigDecimal.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javase/1,5.0/docs/api/java/math/BigDecimal.html');">BigDecimal</a></em> is modified, the user must provide the rule by which the scale will be reduced.  Here I chose the &#8216;half-even&#8217; method, which is also the one used by applications that support numeric analysis (such as Excel) since it provides a more even distribution of discrepancies over larger sets of data.  For more information, have a look at the documentation for the<em> <a href="http://download.oracle.com/javase/1,5.0/docs/api/java/math/RoundingMode.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javase/1,5.0/docs/api/java/math/RoundingMode.html');">java.math.RoundingMode</a></em> enumeration.</p>
<p>Further study of the Java Persistence API will uncover many other &#8216;callback&#8217; annotations that can be used to provide finer control over entity life-cycle without having to write large amounts of custom code.</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/fQfBj_Gpzek" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/06/13/tweaking-persistence-with-prepersist/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/06/13/tweaking-persistence-with-prepersist/</feedburner:origLink></item>
		<item>
		<title>Dr. Mindbender, Or How I Learned To Stop Worrying And Love Hibernate</title>
		<link>http://feedproxy.google.com/~r/summa-tech/LoQU/~3/Pv2eTNURxfQ/</link>
		<comments>http://www.summa-tech.com/blog/2011/06/07/dr-mindbender-or-how-i-learned-to-stop-worrying-and-love-hibernate/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 11:51:08 +0000</pubDate>
		<dc:creator>Steve Ayers</dc:creator>
		
		<category><![CDATA[Agile and Development]]></category>

		<category><![CDATA[hibernate]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[ORM]]></category>

		<category><![CDATA[persistence]]></category>

		<guid isPermaLink="false">http://www.summa-tech.com/blog/?p=3414</guid>
		<description><![CDATA[I’ll admit I was wrong.

For years, I have been beating the drum about town, proselytizing my distaste for <a href="http://www.hibernate.org/">Hibernate</a>.  I told everyone that would listen what my opinions were.  ‘It only gets in the way’, I said.  ‘Its too much of a black box’.

And while some of those notions still hold true, I am here today to admit I was wrong in that Hibernate is not a total obstacle of a framework.  In the right situations and circumstances, it actually is very nice to have on your side.  In the wrong situations, however, it is a nightmare.  It is not something that can be forcefed into every situation and while it has its benefits, using it in the wrong project will provide nothing but heartache.  Trust me, I know from experience.  It is the <a href="http://en.wikipedia.org/wiki/Doctor_Mindbender">Dr. Mindbender</a> of frameworks:  use it where it should be and it’s a peace-loving orthodontist.  Misuse it and you have a hateful, deceitful villain with a proclivity for cybernetics and brain-scrambling.  ]]></description>
			<content:encoded><![CDATA[<p>I’ll admit I was wrong.</p>
<p>For years, I have been beating the drum about town, proselytizing my distaste for <a href="http://www.hibernate.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.hibernate.org/');">Hibernate</a>.  I told everyone that would listen what my opinions were.  ‘It only gets in the way’, I said.  ‘Its too much of a black box’.</p>
<p>And while some of those notions still hold true, I am here today to admit I was wrong in that Hibernate is not a total obstacle of a framework.  In the right situations and circumstances, it actually is very nice to have on your side.  In the wrong situations, however, it is a nightmare.  It is not something that can be forcefed into every situation and while it has its benefits, using it in the wrong project will provide nothing but heartache.  Trust me, I know from experience.  It is the <a href="http://en.wikipedia.org/wiki/Doctor_Mindbender" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://en.wikipedia.org/wiki/Doctor_Mindbender');">Dr. Mindbender</a> of frameworks:  use it where it should be and it’s a peace-loving orthodontist.  Misuse it and you have a hateful, deceitful villain with a proclivity for cybernetics and brain-scrambling.  </p>
<p>I spent a decent amount of time on a project that flouted tried-and-true Hibernate conventions.  Admittedly, this was my first proper working experience on a major project with it, so naturally, I became prejudiced against it.  ‘THIS is what all the Hibernate fuss is about?’, I said, the platform for my future drum-beating beginning to take hold.  ‘I know how to write my own database queries, no thanks’.<br />
So from then on, I became a zealot, proudly jutting out my chest in interviews and on projects about how it was worthless, how I’d rather just use easier approaches like <a href="http://www.springsource.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.springsource.org/');">Spring</a> and <a href="http://download.oracle.com/javase/6/docs/technotes/guides/jdbc/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://download.oracle.com/javase/6/docs/technotes/guides/jdbc/');">JDBC</a>.  </p>
<p>Then, something unexpected happened.</p>
<p>I worked on a project that actually made sensible use of Hibernate.  I got to see how a proper persistence-mapping file was created.  I saw first-hand some of the benefits of Hibernate that I didn’t even know existed; benefits that weren’t in my egotistical arsenal of query-writing and transactional coding.</p>
<p>But, old habits die hard.  In technology, you learn as you go, so it makes no sense to completely flip-flop from one side to another.  To be a good developer (to go from journeyman to master, if you will), you should be an amalgam of your experiences.  Draw from what you learned and make informed decisions.  </p>
<p>So, to prove my point, I will outline the good and the bad of Hibernate.  I will tell you when to use it, when not to, and some practices to avoid.  And hopefully, you’ll recognize when you should make use of it and when you should avoid it like the plague.  After all, there’s a time and place for everything.</p>
<h3>The Good</h3>
<p><strong>No Query Writing</strong></p>
<p>Probably the biggest and highly-touted feature of Hibernate is that it abstracts the database layer away from the developer.  No more fiddling around with DB queries and getting your hands unnecessarily dirty with database connections.  Through simple methods such as Session.load() and Session.get(), retrieving an object is simple.  In addition, Hibernate’s Criteria API makes complex joins relatively simple and easy to create.</p>
<p>For example, suppose your system has an Order object which has a many-to-one association to a Customer object and the association is by Customer ID.  Further suppose that the query to retrieve both orders and customers pits up against two brutally large and inefficiently constructed tables.  If you have not specified a fetch strategy on the relationship, the default behavior for Hibernate is SELECT, which means to retrieve an order, two queries will be run:  one for the Order and one to populate the Customer association.  Normally, what you’d do in plain JDBC world is to simply join these two queries together on the Customer ID, which is a process that can be a pain, especially if the queries are large, the join columns are complex, or the queries are stored in code (requiring a recompile).<br />
However, in Hibernate, you simply change the fetch strategy to JOIN in the mapping file and voila, Hibernate joins the queries together and retrieving an Order runs one query, bringing back Order details and Customer details in one shot.</p>
<p><strong>Caching</strong></p>
<p>Caching is an item that could be its own blog post (I smell sequel!), but I will touch on it here.  There are three areas of caching involved with Hibernate:  1st-level, or session-caching, 2nd-level caching, and query caching.</p>
<p>In a nutshell, session caching involves the ability of Hibernate to store objects in cache scoped to the current Hibernate session.  What this means in layman’s terms is that the following code: </p>
<pre name="code" class="java:nocontrols">
  Session.load(MyObject.class, 123);
  // Other logic here
  Session.load(MyObject.class, 123);
</pre>
<p>will only invoke one query for MyObject.  The initial invocation hit the database and stored the information in Hibernate’s session cache.  Since we are still in the same session, another request for that object will simply retrieve it from the session cache and not pull it from the database.</p>
<p>The second-level cache and query cache work together and are scoped across Hibernate sessions.  The 2nd level-cache stores IDs of objects keyed to the respective object values (not the objects themselves).  The query cache stores WHERE clauses and their bound parameters keyed to object IDs.  Used together they represent a powerful way to improve performance by storing oft-requested information in a cache and minimizing the hits on the database over time.  If your application is easily cacheable, then Hibernate could be a good choice for you.  It can really speed up response time by eliminating all that expensive database interaction.  </p>
<p>So, how do you know if your application has good cache candidates?  Well, stay tuned for the sequel.  You didn’t learn the back story of Don Corleone in Godfather I did you?</p>
<p><strong>DB From Scratch</strong></p>
<p>One such area that begs for Hibernate is when the database is being designed from scratch.  This is not an existing database you are trying to shoehorn Hibernate in front of, this is one that can be designed with an ORM solution in mind.  It is one that can be designed for abstractions.</p>
<p>As a result, you can take a more object-oriented approach to fashioning the database and its relationships.  You can assure that tables are created that are easily modeled to objects and that the relationships that are defined are properly mapped.  If you think in terms of the system and how Hibernate functions, designing the database will be easy and as a result, Hibernate will be a seamless integration into your system.  </p>
<p><strong>Lower DB Learning Curve</strong></p>
<p>From a consultant’s point-of-view, it makes it far easier to learn the database and its relationships when a proper and well-documented implementation of Hibernate is in place.  Learning database tables and their structures is simple just by scanning the persistence-mapping file.  No need looking at cryptic table names and columns where you have to first parse the English translation of them before you can even think of how they all relate together.</p>
<p>Further, the Hibernate entity objects make a developer-friendly way to look at the business model.  Everything is laid out into handy Java objects, enabling you to take a more code-centered approach towards learning the domain.  In addition, learning data types of fields is extremely easy and all of this makes onboarding that much faster.  Which would you rather spend your time learning:</p>
<p><strong><em>ORD_MASTER</em></p>
<p>ORD_ID<br />
ORD_NM<br />
CST_ID<br />
QTY<br />
TTL<br />
STS	</strong></p>
<p>Or this:</p>
<pre name="code" class="java:nocontrols">
public class Order {
    	private String orderId;

    	private String orderName;

    	private Long customerId;

    	private Integer quantity;

    	private Integer total;

    	private String status;
}
</pre>
<p>So, while this may not be necessarily a reason to implement Hibernate, it is one positive aspect of it.  As a consultant, anything that enables you to learn the client domain faster is a good thing.</p>
<h3>The Bad</h3>
<p><strong>Query Writing</strong></p>
<p>OK, so maybe I was wrong when I said there’s NO query writing.  Sometimes there is.  Hibernate has its own query language called the (wait for it) <a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html');">Hibernate Query Language</a>, or HQL.  In addition, its syntax is not completely identical to SQL, which I’m guessing is the database language in which you spent a few years dabbling.</p>
<p>Well, they say to learn to new a language once a year, so here’s your newest one.  Luckily, you shouldn’t need to use this that often, especially if you have a well-crafted mapping file and make efficient use of the Criteria API.  Any ORM worth its salt and that prides itself on database layer abstraction should not force the developer to rely on query-writing, even if it is relatively object-oriented.  </p>
<p><strong>Unwieldy Legacy Databases</strong></p>
<p>Legacy databases pose a problem for Hibernate.  There are many aspects of a database that can creep in over time and most of them do not react well when an ORM pokes its nose in on their business.</p>
<p>One such sign that Hibernate is a bad idea is business logic in the database, such as in PL/SQL packages and procedures.  This type of logic works behind Hibernate’s back and provides nothing but headaches to attached entity objects in your code.  For example:</p>
<p>MyObject is retrieved from the database.  While it is hydrated, a procedure is invoked in the database that updates a few tables, including the table to which MyObject is connected.  Now, your object has stale data inside that it thinks is valid.  You now have to flush your object and get the up-to-date data.  This kind of thing can be difficult to fix and even more difficult to diagnose.  </p>
<p>In addition, with legacy databases, often times developers tend to know the schema and inner workings extremely well.  They become intimately familiar with the poor performing tables, where the indices are, and how the relationships work.  As such, sticking Hibernate in front of them makes for an extremely problematic transition.  They will see Hibernate as a black box obstacle that they have to defer to regarding the database.  When you have a group of developers who are used to getting their hands dirty with the data, sticking an ORM framework in their way is going to cause problems.</p>
<p><strong>Unnecessary Information</strong></p>
<p>This item was one of my talking points during my Great Anti-Hibernate Crusade.  I’ve grown less vitriolic with this concern in my old age, but its still something I have a bit of trouble with and have never really received a complete and acceptable answer.</p>
<p>Modeling data to objects using an ORM like Hibernate simply returns more data than needed.  Period.  There are going to be times when you need the values of five columns from a fifty-column table.  In addition, this table could have a plethora of one-to-many associations which are fetched eagerly.  So, for your five columns you are returning back 47+ values you don’t need and running who knows how many queries needlessly.  Sure, you could turn off the eager-loading, but that affects any other logic that needs these associations at the time they’re loaded.</p>
<p>The explanations or resolutions for this I’ve been proposed over the years are that you should design your system in a way where model objects can be used throughout all layers.  In a perfect world, that seems reasonable.  But user demands are not always reasonable.  So, what happens when they request to see a popup on screen showing only those five values from that fifty-column behemoth?  Should I tell them I can’t because it doesn’t work well with model objects?  </p>
<p>Designing with a model object approach in mind is a great idea with new development, but applying this to legacy code is a headache.  </p>
<p>The way I see it, you have three options in the above scenario:</p>
<p>1.	Just retrieve the object as its modeled and send the mounds of information back even if its not needed<br />
2.	Use a Data Transfer Object<br />
3.	Consider a refactoring of the modeling / relationships.</p>
<p>All have tradeoffs and none seem like a silver bullet approach.  The last object is probably not going to happen.  This is especially true if this is a legacy system with rotting design.  </p>
<p>The first option is most likely, but as I said will result in needless data and/or queries being run, but admittedly this is something that could be mitigated with caching strategies.</p>
<p>The second option is sort of like throwing in the towel.  Its like admitting you were beaten by requirements.  The second you let DTOs creep into the mix, things start to get infected and you’re losing the very foundation on which you built your Hibernate architecture in the first place.</p>
<p>So, that is what I’ve learned so far in my love-hate relationship with Hibernate.  I suspect many developers have a love-hate relationship with a lot of tools and mine just happens to be this one.  I think it benefits a developer to see the good and bad of each and not just develop unfounded opinions based on one bad experience.  That way, they can make an informed decision in any circumstance.  Learning to do this allows you to have an open-mind and grow in your knowledge, eventually becoming an evil genius capable of mind control and dentistry, like Dr. Mindbender.</p>
<p>&copy;2012 <a href="http://www.summa-tech.com/blog" >Summa Blog</a>. All Rights Reserved.</p>.<img src="http://feeds.feedburner.com/~r/summa-tech/LoQU/~4/Pv2eTNURxfQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.summa-tech.com/blog/2011/06/07/dr-mindbender-or-how-i-learned-to-stop-worrying-and-love-hibernate/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.summa-tech.com/blog/2011/06/07/dr-mindbender-or-how-i-learned-to-stop-worrying-and-love-hibernate/</feedburner:origLink></item>
	</channel>
</rss>

