<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2enclosuresfull.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><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:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>JAW Speak</title>
	
	<link>http://jawspeak.com</link>
	<description>Jonathan Andrew Wolter</description>
	<pubDate>Sun, 30 Nov 2008 20:17:28 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.5</generator>
	<language>en</language>
			<itunes:explicit>no</itunes:explicit><itunes:subtitle>Jonathan Andrew Wolter</itunes:subtitle><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/JAWspeak" type="application/rss+xml" /><feedburner:emailServiceId>464414</feedburner:emailServiceId><feedburner:feedburnerHostname>http://www.feedburner.com</feedburner:feedburnerHostname><item>
		<title>Introducting JAW’s Very Simple GWT Html Template</title>
		<link>http://feeds.feedburner.com/~r/JAWspeak/~3/469761911/</link>
		<comments>http://jawspeak.com/2008/11/29/introducting-jaws-very-simple-gwt-html-template/#comments</comments>
		<pubDate>Sat, 29 Nov 2008 23:44:15 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[gwt]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=62</guid>
		<description><![CDATA[At a recent client of ThoughtWorks&#8217;, I was writing complex GWT views. If you&#8217;ve ever worked with Google Web Toolkit, you know the pain that this can involve. Instead of creating HTML files of templates, you need to build the DOM programatically with your own widgets, 3rd party widgets, or the basic widgets GWT gives [...]]]></description>
			<content:encoded><![CDATA[<p>At a recent client of <a href="http://www.thoughtworks.com/our-clients/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.thoughtworks.com');">ThoughtWorks&#8217;</a>, I was writing complex <a href="http://code.google.com/webtoolkit/" onclick="javascript:pageTracker._trackPageview('/outbound/article/code.google.com');">GWT</a> views. If you&#8217;ve ever worked with Google Web Toolkit, you know the pain that this can involve. Instead of creating HTML files of templates, you need to build the DOM programatically with your own widgets, 3rd party widgets, or the basic widgets GWT gives you. I wrote a simple templating system to meet my needs. Maybe it will help you too, please feel free to request features and share if it helps you.</p>
<p>If you try <a href="http://code.google.com/p/jaws-very-simple-gwt-template/" onclick="javascript:pageTracker._trackPageview('/outbound/article/code.google.com');">JAW&#8217;s Very Simple GWT</a> Template, all you need to do is follow a few conventions and you get the following.</p>
<ol>
<li>Create a html file with your complex layout. For instance a really fancy 12&#215;12 html table with all sorts of colspans and rowspans for displaying detailed tabular data.</li>
<li>Create a value object (in Java, on the GWT side) that you want to automatically use to dump some attributes into the template.</li>
<li>In the html template, use <tt>${valueObject.someProperty}</tt> style notation where you want automatic setting of values into the template.</li>
<li>In the html template, use <tt>$${specialDoubleDollarSign}</tt> notation where you want to manually bind the template values.</li>
</ol>
<p>Really, it is very simple and no frills. It solved my need of presenting data in a visually rich way, into html that a designer could produce without any knowledge of GWT. Also, you can embed it into other widgets, or other widgets into it.</p>
<p>I think it&#8217;s cool in two ways:</p>
<ol>
<li>Automatic data binding from your value object, into the <tt>${myObj.property}</tt> template slots.</li>
<li>Ability to manually attach complex widgets (with GWT defined event behavior), into the <tt>$${doubleDollarSignSlot}</tt> template slots.</li>
</ol>
<p>I&#8217;ve created a Google Code <a href="http://code.google.com/p/jaws-very-simple-gwt-template/" onclick="javascript:pageTracker._trackPageview('/outbound/article/code.google.com');">project</a> with the source code and some examples (as tests). Please take a look and leave criticism and feedback.</p>
<p>If you&#8217;re curious how this is implemented, it&#8217;s all with defered binding and generators in GWT. As all code I actually want to work, I&#8217;ve test driven it and you can look at the tests for details.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/JAWspeak?a=zSHUN"><img src="http://feeds.feedburner.com/~f/JAWspeak?i=zSHUN" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/469761911" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2008/11/29/introducting-jaws-very-simple-gwt-html-template/feed/</wfw:commentRss>
		<feedburner:origLink>http://jawspeak.com/2008/11/29/introducting-jaws-very-simple-gwt-html-template/</feedburner:origLink></item>
		<item>
		<title>Linking to Miško’s, Russ’ and my Testability Guide</title>
		<link>http://feeds.feedburner.com/~r/JAWspeak/~3/469699499/</link>
		<comments>http://jawspeak.com/2008/11/29/linking-to-miskos-russ-and-my-testability-guide/#comments</comments>
		<pubDate>Sat, 29 Nov 2008 22:26:26 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[testability]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=60</guid>
		<description><![CDATA[I had the great pleasure of collaborating with Miško Hevery and Russ Rufer in creating the Guide for Writing Testable Code. Please feel free to check it out, and leave comments here or on his blog.
Here&#8217;s a peek at the different flaws to watch out for, and warn your co-workers about. If you see this [...]]]></description>
			<content:encoded><![CDATA[<p>I had the great pleasure of collaborating with <a href="http://misko.hevery.com/about/" onclick="javascript:pageTracker._trackPageview('/outbound/article/misko.hevery.com');">Miško Hevery</a> and <a href="http://groups.yahoo.com/group/siliconvalleypatterns/" onclick="javascript:pageTracker._trackPageview('/outbound/article/groups.yahoo.com');">Russ Rufer</a> in creating the <a href="http://misko.hevery.com/code-reviewers-guide/" onclick="javascript:pageTracker._trackPageview('/outbound/article/misko.hevery.com');">Guide for Writing Testable Code</a>. Please feel free to check it out, and leave comments here or on his blog.</p>
<p>Here&#8217;s a peek at the different flaws to watch out for, and warn your co-workers about. If you see this in code that is getting checked in, bring it to the attention to your team. See Miško&#8217;s <a href="http://misko.hevery.com/2008/11/24/guide-to-writing-testable-code/" onclick="javascript:pageTracker._trackPageview('/outbound/article/misko.hevery.com');">post for the full list</a>.</p>
<p><a href="http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/">Flaw #1: Constructor does Real Work (link)<br />
</a></p>
<ul>
<li>If you have a constructor that is doing &#8220;work&#8221; you&#8217;ve established a contract that everyone who wants to create this object also is forced to wait for that &#8220;work&#8221; to happen. This becomes a huge problem in small unit tests. Frequently unit tests create many, many instances of the object under test - and any work you do in the constructor slows down tests.</li>
<li>The solution? Break up the responsibility into two objects: a builder of factory to do all the heavy lifting to construct the object, and whatever the original object was that had the heavy constructor. When you split the responsibilities up you will have a better object oriented design, and make it easy for more flexible construction. If you&#8217;re tempted to create an <em>init()</em> method and put the work in there - avoid this siren song. It&#8217;s a smell of mixed responsibilities and a poorly behaving object that isn&#8217;t really ready when the constructor completes.</li>
<li>Warning signs are:
<ul>
<li><span style="font-family: Courier New,monospace;">new</span> keyword in a constructor or at field declaration</li>
<li> Static method calls in a constructor or at 	field declaration</li>
<li> Anything more than field assignment in 	constructors</li>
<li> Object not fully initialized after the 	constructor finishes (watch out for <span style="font-family: Courier New,monospace;">initialize</span> methods)</li>
<li> Control flow (conditional or looping logic) 	in a constructor</li>
<li> Code does complex object graph construction 	inside a constructor rather than using a factory or builder</li>
<li> Adding or using an initialization block</li>
</ul>
</li>
</ul>
<p><a href="http://misko.hevery.com/code-reviewers-guide/flaw-digging-into-collaborators/">Flaw #2: Digging into Collaborators (link)<br />
</a></p>
<ul>
<li>Jumping from one object to another to another to get what you want makes for hard to test and hard to refactor code. This is commonly viewed as the Law of Demeter violation, however you can dig into collaborators without breaking the letter of the law. This is hard to work with in tests, because your tests need to do a great deal of setup stuffing objects in objects into other objects, or else you&#8217;ll get null pointers.</li>
<li>Warning signs are:
<ul>
<li>Objects are passed in but never used directly 	(only used to get access to other objects)</li>
<li>Law of Demeter violation: method call chain 	walks an object graph with more than one dot (<span style="font-family: Courier New,monospace;">.</span>)</li>
<li>Suspicious names: <span style="font-family: Courier New,monospace;">context</span>, 	<span style="font-family: Courier New,monospace;">environment</span>, <span style="font-family: Courier New,monospace;">principal</span>, 	<span style="font-family: Courier New,monospace;">container</span>, or manager</li>
</ul>
</li>
</ul>
<p><a href="http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/">Flaw #3: Brittle Global State &amp; Singletons (link)<br />
</a></p>
<ul>
<li>Global state (usually made possible through the <em>static</em> keyword in Java) creates hard to test and modify code. Parallelizing tests is often impossible, and tests that forget to clean up the global state after running interact undesirably with other tests (causing unexpected failures).</li>
<li>Warning signs are:
<ul>
<li>Adding or using singletons</li>
<li>Adding or using static fields or static 	methods</li>
<li>Adding or using static initialization blocks</li>
<li>Adding or using registries</li>
<li>Adding or using service locators</li>
</ul>
</li>
</ul>
<p><a href="http://misko.hevery.com/code-reviewers-guide/flaw-class-does-too-much/">Flaw #4: Class Does Too Much (link)<br />
</a></p>
<ul>
<li>Object oriented design allows you to split responsibilities into individually tested objects. Using an object oriented language does not prevent people from writing procedural code. In fact, most times when someone does not want to write tests it is because their code is hard to test.</li>
<li>Warning Signs:
<ul>
<li>Summing up what the class does includes the 	word “and”</li>
<li>Class would be challenging for new team 	members to read and quickly “get it”</li>
<li>Class has fields that are only used in some 	methods</li>
<li>Class has static methods that only operate on 	parameters</li>
</ul>
</li>
</ul>
<p>There&#8217;s typically no magic wand to wave and make hard to test code instantly testable. Engineers need to have an open mind and learn how to write code designed for testability. (In my experience 90% of the time this involves test driven design and test driven development.) These ideas above, and many of Miško&#8217;s other posts are a fantastic starting point for adopting that new way of thinking.</p>
<p>Please link it up with your favorite testability mindset readings.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/JAWspeak?a=9ZIUN"><img src="http://feeds.feedburner.com/~f/JAWspeak?i=9ZIUN" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/469699499" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2008/11/29/linking-to-miskos-russ-and-my-testability-guide/feed/</wfw:commentRss>
		<feedburner:origLink>http://jawspeak.com/2008/11/29/linking-to-miskos-russ-and-my-testability-guide/</feedburner:origLink></item>
		<item>
		<title>Recommended: etckeeper to keep all your server’s /etc in git (or bzr or hg)</title>
		<link>http://feeds.feedburner.com/~r/JAWspeak/~3/462572323/</link>
		<comments>http://jawspeak.com/2008/11/23/recommended-etckeeper-to-keep-all-your-servers-etc-in-git-or-bzr-or-hg/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 06:52:11 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[git]]></category>

		<category><![CDATA[servers]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=52</guid>
		<description><![CDATA[I&#8217;m using etckeeper to keep my /etc directory in version control (git).
When you make changes to a server, there are always risks. And even if you have a great backup strategy (I recommend backupninja), sometimes you change a config in the wrong way, which can ruin an otherwise great night. Why don&#8217;t we have an [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m using etckeeper to keep my <tt>/etc</tt> directory in version control (git).</p>
<p>When you make changes to a server, there are always risks. And even if you have a great backup strategy (I recommend <a href="http://riseuplabs.org/backupninja/" onclick="javascript:pageTracker._trackPageview('/outbound/article/riseuplabs.org');">backupninja</a>), sometimes you change a config in the wrong way, which can ruin an otherwise great night. Why don&#8217;t we have an easy way to version control this very important configuration directory? (Ubuntu is <a href="https://wiki.ubuntu.com/VersionControlledEtc" onclick="javascript:pageTracker._trackPageview('/outbound/article/wiki.ubuntu.com');">working on it</a>).</p>
<p>Here&#8217;s what <tt>$ sudo gitk</tt> will show you after a few changes in your <tt>/etc</tt>.<br />
<a title="etckeeper with git by JAWspeak, on Flickr" href="http://www.flickr.com/photos/jawspeak/3052312928/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.flickr.com');"><img src="http://farm4.static.flickr.com/3275/3052312928_ca689d5ca7_o.jpg" alt="etckeeper with git" width="341" height="372" /></a></p>
<p>It&#8217;s no surprise that this comes from Joey Hess, who also wrote <a href="http://joey.kitenet.net/svnhome/" onclick="javascript:pageTracker._trackPageview('/outbound/article/joey.kitenet.net');">how to keep your life in svn</a>. I was going to <a href="http://linuxgazette.net/131/shirley.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/linuxgazette.net');">check into subversion all of  <tt>/etc</tt></a>, but this has been a better experience so far: it has automatic hooks to do pre and post apt-get update commits. So you can more easily see what each package does to your configuration. Also, etckeeper takes care of permissions where svn can&#8217;t.</p>
<p>If you&#8217;re ready to install, here&#8217;s how you do it. I didn&#8217;t use the deb distribution because it is quite out of date, instead I pulled down the newest directly from Joey&#8217;s git repository.</p>
<pre>$ sudo apt-get install git-core gitk
$ cd ~/
$ git://git.kitenet.net/etckeeper
$ cd etckeeper
( read the README and INSTALL files )
( possibly edit etckeeper.conf if you want to use bazaar or mecurial instead of git )
$ sudo make install  ( It's okay if it warns that bzr support not installed if you're not using it )
# sudo etckeeper init
$ cd /etc
$ sudo git status
$ sudo git commit -m "Initial checkin"</pre>
<p>That&#8217;s it! Check out the <a href="http://git.kitenet.net/?p=etckeeper.git;a=blob_plain;f=README;hb=HEAD" onclick="javascript:pageTracker._trackPageview('/outbound/article/git.kitenet.net');">README</a> for day to day examples.</p>
<p>Whenever you use <tt>apt</tt> to install a program, it checks in any uncommitted changes, and then checks in the /etc after apt finishes. <tt>/etc</tt> is just a regular git repository (except for security permissions require using sudo), so you can also commit changes anytime you want.</p>
<p>Here&#8217;s another person&#8217;s <a href="http://daniel.hahler.de/track_changes_to_etc_configuration_files" onclick="javascript:pageTracker._trackPageview('/outbound/article/daniel.hahler.de');">take on etckeeper</a>. New to Git? Check out <a href="http://eagain.net/articles/git-for-computer-scientists/" onclick="javascript:pageTracker._trackPageview('/outbound/article/eagain.net');">Git for Computer Scientists.</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/JAWspeak?a=f2L7N"><img src="http://feeds.feedburner.com/~f/JAWspeak?i=f2L7N" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/462572323" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2008/11/23/recommended-etckeeper-to-keep-all-your-servers-etc-in-git-or-bzr-or-hg/feed/</wfw:commentRss>
		<feedburner:origLink>http://jawspeak.com/2008/11/23/recommended-etckeeper-to-keep-all-your-servers-etc-in-git-or-bzr-or-hg/</feedburner:origLink></item>
		<item>
		<title>Using Hibernate UserType’s for oddly formatted legacy tables (with tests)</title>
		<link>http://feeds.feedburner.com/~r/JAWspeak/~3/448391792/</link>
		<comments>http://jawspeak.com/2008/11/10/using-hibernate-usertypes-for-oddly-formatted-legacy-tables-with-tests/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 06:23:51 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[hibernate]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=42</guid>
		<description><![CDATA[If you are using Hibernate with an existing (ahem, &#8220;creative&#8221;) database schema sooner or later you will be stuck with a field that Hibernate can&#8217;t parse. Say there is a Dimension column which stores the integer dimensions as a string &#8220;003X001X010&#8243;. That would be 3 by 1 by 10 units.
You can implement UserType to transparently [...]]]></description>
			<content:encoded><![CDATA[<p>If you are using Hibernate with an existing (ahem, &#8220;creative&#8221;) database schema sooner or later you will be stuck with a field that Hibernate can&#8217;t parse. Say there is a Dimension column which stores the integer dimensions as a string <tt>&#8220;003X001X010&#8243;</tt>. That would be 3 by 1 by 10 units.</p>
<p>You can implement <a title="javadoc for UserType" href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/usertype/UserType.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.hibernate.org');">UserType</a> to transparently convert a proprietorially formatted field into first class objects of your choice.</p>
<p>And you can do it in a testable manner.</p>
<p>I&#8217;ll show the tests first, then the custom UserType. Right after the bump. (Click the post permalink to read the rest).</p>
<p><span id="more-42"></span></p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * @author Jonathan Andrew Wolter
 */</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> DimensionsUserTypeTest <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Fortunately there is no work done in the constructor, so we can easily create an instance</span>
  <span style="color: #666666; font-style: italic;">// of a DimensionsUserType for exercising.</span>
  <span style="color: #000000; font-weight: bold;">private</span> DimensionsUserType dimensionsUserType <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DimensionsUserType<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
  @Test
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> readsCorrectDimensions<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// See how we can easily call our &quot;sprouted method&quot; in the test</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span>, dimensionsUserType.<span style="color: #006633;">processNullSafeGet</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;001X002X003&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span>,<span style="color: #cc66cc;">200</span>,<span style="color: #cc66cc;">300</span><span style="color: #009900;">&#41;</span>, dimensionsUserType.<span style="color: #006633;">processNullSafeGet</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;100X200X300&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span>, dimensionsUserType.<span style="color: #006633;">processNullSafeGet</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;01X2X3&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Test
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> readsInvalidDimensions<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span>, dimensionsUserType.<span style="color: #006633;">processNullSafeGet</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Test
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setsCorrectDimensions<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;001X002X003&quot;</span>, dimensionsUserType.<span style="color: #006633;">processNullSafeSet</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;100X200X300&quot;</span>, dimensionsUserType.<span style="color: #006633;">processNullSafeSet</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span>, <span style="color: #cc66cc;">200</span>, <span style="color: #cc66cc;">300</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Test
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setIncorrectDimensions<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    assertThat<span style="color: #009900;">&#40;</span>dimensionsUserType.<span style="color: #006633;">processNullSafeSet</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1000</span>,<span style="color: #cc66cc;">2000</span>,<span style="color: #cc66cc;">3000</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>, is<span style="color: #009900;">&#40;</span>nullValue<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
    assertThat<span style="color: #009900;">&#40;</span>dimensionsUserType.<span style="color: #006633;">processNullSafeSet</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1000</span>,<span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">3000</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>, is<span style="color: #009900;">&#40;</span>nullValue<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Test
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setsDimensionsWithDecimalRoundsToInteger<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span>, dimensionsUserType.<span style="color: #006633;">processNullSafeGet</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;1.5X2.X3.4&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>,0,<span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span>, dimensionsUserType.<span style="color: #006633;">processNullSafeGet</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;1.0X0.2X3.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Test
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setsNullDimensions<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    assertThat<span style="color: #009900;">&#40;</span>dimensionsUserType.<span style="color: #006633;">processNullSafeSet</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>, is<span style="color: #009900;">&#40;</span>nullValue<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Test
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> interfaceContractualMethods<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    assertEquals<span style="color: #009900;">&#40;</span>DimensionsDto.<span style="color: #000000; font-weight: bold;">class</span>, dimensionsUserType.<span style="color: #006633;">returnedClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
    assertThat<span style="color: #009900;">&#40;</span>dimensionsUserType.<span style="color: #006633;">sqlTypes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, is<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span> <span style="color: #003399;">Types</span>.<span style="color: #006633;">VARCHAR</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Test
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> deepCopyAndEquals<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// VERY IMPORTANT!</span>
    <span style="color: #666666; font-style: italic;">// If this is not implemented correctly, you can potentially be forcing Hibernate to make</span>
    <span style="color: #666666; font-style: italic;">// update calls on EVERY object containing a field of this UserType.</span>
    assertTrue<span style="color: #009900;">&#40;</span>dimensionsUserType.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span>, dimensionsUserType.<span style="color: #006633;">deepCopy</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
    DimensionsDto dimensions123 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span>;
    assertFalse<span style="color: #009900;">&#40;</span>dimensionsUserType.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span>, dimensionsUserType.<span style="color: #006633;">deepCopy</span><span style="color: #009900;">&#40;</span>dimensions123<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
    assertFalse<span style="color: #009900;">&#40;</span>dimensionsUserType.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>dimensions123, dimensionsUserType.<span style="color: #006633;">deepCopy</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
    assertTrue<span style="color: #009900;">&#40;</span>dimensionsUserType.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>
            <span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span>,
            dimensionsUserType.<span style="color: #006633;">deepCopy</span><span style="color: #009900;">&#40;</span>dimensions123<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
    assertFalse<span style="color: #009900;">&#40;</span>dimensionsUserType.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>
            <span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span>,
            dimensionsUserType.<span style="color: #006633;">deepCopy</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
    DimensionsDto old <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span>;
    assertNotSame<span style="color: #009900;">&#40;</span>old, dimensionsUserType.<span style="color: #006633;">deepCopy</span><span style="color: #009900;">&#40;</span>old<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The class under test is our implementation of UserType:</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Custom database field type to convert (transparently) between &quot;004X005X006&quot; varchar fields
 * into a DimensionsDto object of width, length and height properties.
 * @author Jonathan Andrew Wolter
 */</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> DimensionsUserType <span style="color: #000000; font-weight: bold;">implements</span> UserType <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> assemble<span style="color: #009900;">&#40;</span><span style="color: #003399;">Serializable</span> arg0, <span style="color: #003399;">Object</span> arg1<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> HibernateException <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// TODO Tests don't indicate we need to implement this yet.</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> deepCopy<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> dimensions<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> HibernateException <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>dimensions <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span>;
    <span style="color: #009900;">&#125;</span>
    DimensionsDto dim <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>DimensionsDto<span style="color: #009900;">&#41;</span>dimensions;
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span>dim.<span style="color: #006633;">getLength</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, dim.<span style="color: #006633;">getWidth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, dim.<span style="color: #006633;">getHeight</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Serializable</span> disassemble<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> arg0<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> HibernateException <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// TODO Tests don't indicate we need this now</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> equals<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> dimensions1, <span style="color: #003399;">Object</span> dimensions2<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> HibernateException <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Extremely, ultra, very important to implement correctly, otherwise we could read out</span>
    <span style="color: #666666; font-style: italic;">// a value from the database, make no changes to the object with the field of type</span>
    <span style="color: #666666; font-style: italic;">// DimensionsUserType, and then isDirty would be true and Hibernate would be forced to make</span>
    <span style="color: #666666; font-style: italic;">// an update statement for every object with this type read.</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>dimensions1 <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> dimensions2 <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span>;
    <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>dimensions1 <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span> || dimensions2 <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span>;
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">return</span> dimensions1.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>dimensions2<span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> hashCode<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> dimensions<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> HibernateException <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Very important to implement correctly</span>
    <span style="color: #000000; font-weight: bold;">return</span> dimensions.<span style="color: #006633;">hashCode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> isMutable<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//  Tests are saying it is not mutable is easier for now, as the application is read only,</span>
    <span style="color: #666666; font-style: italic;">// we may need to revisit this later.</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #008000; font-style: italic; font-weight: bold;">/** What Hibernate calls when it wants to read a field annoated as using the Type declared by
   * this UserType implementation. We convert the varcar field into a first class DimensionsDto
   * object.
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> nullSafeGet<span style="color: #009900;">&#40;</span><span style="color: #003399;">ResultSet</span> resultSet, <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> names, <span style="color: #003399;">Object</span> owner<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> HibernateException,
          <span style="color: #003399;">SQLException</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">String</span> rawDimensions <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span> Hibernate.<span style="color: #006633;">STRING</span>.<span style="color: #006633;">nullSafeGet</span><span style="color: #009900;">&#40;</span>resultSet, names<span style="color: #009900;">&#91;</span>0<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #000000; font-weight: bold;">return</span> processNullSafeGet<span style="color: #009900;">&#40;</span>rawDimensions<span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #008000; font-style: italic; font-weight: bold;">/** Visible for testing. (Sprouted Method)
   *  We call this method directly for testing, because to exercise the {@code nullSafeGet} is
   * difficult in a test. (It would require a ResultSet to be passed in). This method is simple,
   * and can be hammered easily in tests. */</span>
  DimensionsDto processNullSafeGet<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> rawDimensions<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>rawDimensions <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span>;
    <span style="color: #009900;">&#125;</span>
    <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> split <span style="color: #339933;">=</span> rawDimensions.<span style="color: #006633;">split</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;X&quot;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>split.<span style="color: #006633;">length</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">// invalid dimensions</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span>;
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> DimensionsDto<span style="color: #009900;">&#40;</span>
            <span style="color: #003399;">Math</span>.<span style="color: #006633;">round</span><span style="color: #009900;">&#40;</span>valueOf<span style="color: #009900;">&#40;</span>split<span style="color: #009900;">&#91;</span>0<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">floatValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>,
            <span style="color: #003399;">Math</span>.<span style="color: #006633;">round</span><span style="color: #009900;">&#40;</span>valueOf<span style="color: #009900;">&#40;</span>split<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">floatValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>,
            <span style="color: #003399;">Math</span>.<span style="color: #006633;">round</span><span style="color: #009900;">&#40;</span>valueOf<span style="color: #009900;">&#40;</span>split<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">floatValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #008000; font-style: italic; font-weight: bold;">/** The important entrypoint that Hibernate calls when we want to persist an object with a field
   * declared to have this UserType. The DimensionsDto object is passed in, and we then convert it
   * into the proprietary database schema used in the legacy database.
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> nullSafeSet<span style="color: #009900;">&#40;</span><span style="color: #003399;">PreparedStatement</span> ps, <span style="color: #003399;">Object</span> dimensions, <span style="color: #000066; font-weight: bold;">int</span> index<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> HibernateException,
          <span style="color: #003399;">SQLException</span> <span style="color: #009900;">&#123;</span>
    Hibernate.<span style="color: #006633;">STRING</span>.<span style="color: #006633;">nullSafeSet</span><span style="color: #009900;">&#40;</span>ps, processNullSafeSet<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>DimensionsDto<span style="color: #009900;">&#41;</span>dimensions<span style="color: #009900;">&#41;</span>, index<span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #008000; font-style: italic; font-weight: bold;">/** Visible for testing. (Sprouted Method)
   *  We call into this method from the {@code nullSafeSet} above, because that is difficult to
   *  exercise in a test. However, we can call this method all day long. */</span>
  <span style="color: #003399;">String</span> processNullSafeSet<span style="color: #009900;">&#40;</span>DimensionsDto dim<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>dim <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span>;
    <span style="color: #009900;">&#125;</span>
    <span style="color: #003399;">String</span> formattedString <span style="color: #339933;">=</span> <span style="color: #003399;">String</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;%03dX%03dX%03d&quot;</span>, dim.<span style="color: #006633;">getLength</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, dim.<span style="color: #006633;">getWidth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, dim.<span style="color: #006633;">getHeight</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>formattedString.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">11</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">// could throw, but we'll be nice instead, because the data is sometimes dirty.</span>
       <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span>;
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">return</span> formattedString;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> replace<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> arg0, <span style="color: #003399;">Object</span> arg1, <span style="color: #003399;">Object</span> arg2<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> HibernateException <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// TODO not sure if we need this, tests say we don't so far</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #008000; font-style: italic; font-weight: bold;">/** This is the type that we convert TO when using this custom user type. Anywhere you
   * want to use a DimensionsDto object, annotate it with Type(type='xyz.MyUserType') */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">Class</span> returnedClass<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> DimensionsDto.<span style="color: #000000; font-weight: bold;">class</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #008000; font-style: italic; font-weight: bold;">/** This is the SQL time that is stored in the column of the database */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> sqlTypes<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// We return a new array each time, becuase if we used a final array, the elements within</span>
    <span style="color: #666666; font-style: italic;">// could still be mutated.</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span> <span style="color: #003399;">Types</span>.<span style="color: #006633;">VARCHAR</span> <span style="color: #009900;">&#125;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>If you want to read more about this, check out:</p>
<ul>
<li>Hibernate <a href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/usertype/UserType.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.hibernate.org');">JavaDoc on UserType</a></li>
<li>Hibernate docs <a href="http://www.hibernate.org/172.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.hibernate.org');">article</a></li>
<li>This blog <a href="http://i-proving.ca/space/Technologies/Hibernate/User+Types+in+Hibernate" onclick="javascript:pageTracker._trackPageview('/outbound/article/i-proving.ca');">post</a> from the people at Intelliware</li>
</ul>
<p>The alternative to using UserTypes is to have your application code do the translations. And you could isolate this potentially within your Repository / DAO layer. So you&#8217;d guarantee any object handed off to the rest of your application would have Dimension objects, and not an unparsed String. And that still might be the best thing to do sometimes, because UserTypes have one fatal flaw.</p>
<p>The fatal flaw with UserType&#8217;s is they offer no opportunity for dependency injection or configuration. This is a huge disappointment. This means if you need to do more complicated parsing of the raw field, you may be forced to reach out in to the ether and use a static method. Example: what if we parsed some string out of the raw sql row which was a foreign key to another table. How can we look that up? We can&#8217;t inject in a service to do this lookup. Read more at a thread over on the Spring Forums <a href="http://forum.springframework.org/showthread.php?t=37815" onclick="javascript:pageTracker._trackPageview('/outbound/article/forum.springframework.org');">about the lack of DI</a>. If you have any doubts of <a href="http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/" onclick="javascript:pageTracker._trackPageview('/outbound/article/misko.hevery.com');">Singletons and Statics as the worst thing ever</a>, please stand up and argue your point.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/JAWspeak?a=LUmGN"><img src="http://feeds.feedburner.com/~f/JAWspeak?i=LUmGN" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/448391792" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2008/11/10/using-hibernate-usertypes-for-oddly-formatted-legacy-tables-with-tests/feed/</wfw:commentRss>
		<feedburner:origLink>http://jawspeak.com/2008/11/10/using-hibernate-usertypes-for-oddly-formatted-legacy-tables-with-tests/</feedburner:origLink></item>
		<item>
		<title>How to Send Picture Mail via SMS / MMS on the iPhone</title>
		<link>http://feeds.feedburner.com/~r/JAWspeak/~3/446838506/</link>
		<comments>http://jawspeak.com/2008/11/08/how-to-send-picture-mail-via-sms-mms-on-the-iphone/#comments</comments>
		<pubDate>Sat, 08 Nov 2008 21:11:32 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=40</guid>
		<description><![CDATA[If you have an iPhone but have trouble figuring out how to send people text messages with pictures, or MMS messages, here&#8217;s a fix.
Go to the camera app and view the picture you want to send, click the send button and email it to one of the special email addresses below, based on their phone [...]]]></description>
			<content:encoded><![CDATA[<p>If you have an iPhone but have trouble figuring out how to send people text messages with pictures, or <a href="http://en.wikipedia.org/wiki/Multimedia_Messaging_Service" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" mce_href="http://en.wikipedia.org/wiki/Multimedia_Messaging_Service">MMS</a> messages, here&#8217;s a fix.</p>
<p>Go to the camera app and view the picture you want to send, click the send button and email it to one of the special email addresses below, based on their phone number and carrier. These are the <a href="http://en.wikipedia.org/wiki/SMS_gateway" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" mce_href="http://en.wikipedia.org/wiki/SMS_gateway">SMS gateways</a> from the carriers so the picture will be converted into a picture mail message and you&#8217;ll make somebody&#8217;s day (-;</p>
<table class="mceItemTable" style="padding-left: 30px;" mce_style="padding-left: 30px;" border="0" cellspacing="5">
<tbody>
<tr>
<th>Carrier</th>
<th>Email to SMS gateway</th>
</tr>
<tr>
<td><font style="" color="#333333">Alltel</font></td>
<td><font style="" color="#333333">full_phone_number@message.alltel.com</font></td>
</tr>
<tr>
<td><font style="" color="#333333">AT&amp;T (Cingular)</font></td>
<td><font style="" color="#333333">full_phone_number@txt.att.net</font></td>
</tr>
<tr>
<td><font style="" color="#333333">Boost Mobile</font></td>
<td><font style="" color="#333333">full_phone_number@myboostmobile.com</font></td>
</tr>
<tr>
<td><font style="" color="#333333">Einstein PCS</font></td>
<td><font style="" color="#333333">full_phone_number@einsteinmms.com</font></td>
</tr>
<tr>
<td><font style="" color="#333333">Sprint</font></td>
<td><font style="" color="#333333">full_phone_number@messaging.sprintpcs.com</font></td>
</tr>
<tr>
<td><font style="" color="#333333">T-Mobile</font></td>
<td><font style="" color="#333333">full_phone_number@tmomail.net</font></td>
</tr>
<tr>
<td><font style="" color="#333333">US Cellular</font></td>
<td><font style="" color="#333333">full_phone_number@mms.uscc.net</font></td>
</tr>
<tr>
<td><font style="" color="#333333">Verizon Wireless</font></td>
<td><font style="" color="#333333">full_phone_number@vzwpix.com<br />
(@vztext is another, but it strips out pictures)</font></td>
</tr>
<tr>
<td><font style="" color="#333333">Virgin Mobile</font></td>
<td><font style="" color="#333333">full_phone_number@vmobl.com</font></td>
</tr>
</tbody>
</table>
<p></p>
<p>I hope this helps you.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/JAWspeak?a=Jpl4N"><img src="http://feeds.feedburner.com/~f/JAWspeak?i=Jpl4N" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/446838506" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2008/11/08/how-to-send-picture-mail-via-sms-mms-on-the-iphone/feed/</wfw:commentRss>
		<feedburner:origLink>http://jawspeak.com/2008/11/08/how-to-send-picture-mail-via-sms-mms-on-the-iphone/</feedburner:origLink></item>
		<item>
		<title>Obsess About Your Time - 3 Economics Books</title>
		<link>http://feeds.feedburner.com/~r/JAWspeak/~3/444142838/</link>
		<comments>http://jawspeak.com/2007/10/23/obsess-about-your-time-3-economics-books/#comments</comments>
		<pubDate>Tue, 23 Oct 2007 08:03:48 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=32</guid>
		<description><![CDATA[Podcasts are to real-unabridged-books as a raindrop is to a punch in the face. It takes a team of dozens of people to write a really awesome book. And I find them more satisfying and thought provoking than several short podcasts. 
There is nothing so precious as your time. I am only more convinced of [...]]]></description>
			<content:encoded><![CDATA[<p>Podcasts are to real-unabridged-books as a raindrop is to a punch in the face. It takes a team of dozens of people to write a really awesome book. And I find them more satisfying and thought provoking than several short podcasts. </p>
<p>There is nothing so precious as your time. I am only more convinced of this every day.</p>
<p>In the last 3 weeks, I listened to:</p>
<ul>
<li>
<a href="http://en.wikipedia.org/wiki/Confessions_of_an_Economic_Hitman" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">Confessions of an Economic Hitman</a> - even though I don&#8217;t agree with his conclusions, it is an excellent memoir. It was personally thought provoking to listen to a man&#8217;s entire career life unfold in 5 days on my work commute. <em>Takeaway: life can be very exciting, and some people are very powerful. Move faster, driving for results.</em></li>
<li><a href="http://en.wikipedia.org/wiki/Banker_to_the_Poor" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">Banker to the Poor</a> - fantastic book. If you don&#8217;t know about microfinance, this is your introductory course. Imagine in your mind what the marriage of finance and social justice would look like. I read it with friends&#8211;which led to great conversation&#8211;and scheduled a tentative meeting with the great folks at <a href="http://kiva.org" onclick="javascript:pageTracker._trackPageview('/outbound/article/kiva.org');">Kiva.org</a> for my friend with an NGO in India.</li>
<li><a href="http://www.fastcompany.com/bookclub/excerpts/0471648493.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.fastcompany.com');">Travels of a T-Shirt in a Global Economy</a> - So far it&#8217;s entertaining. It is a story telling format asking &#8220;where did your T-Shirt come from?&#8221; And the government-subsidy-enabled-irony of the cotton planted in Texas, woven and sewn in China, and imported back to Florida.</li>
</ul>
<p>To effective time.</p>
<p>UPDATE (10/26): Listening to more of the last book tonight. Around the 3h 30min mark, I learn the key driver our present industrial economy: the <a href="http://en.wikipedia.org/wiki/Spinning_jenny" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">Spinning Jenny</a>. This was a big deal. One person used to have one spinner to make the yarn. In  1764 they suddenly had eight spinners: a tremendous productivity boost in an under supplied marketplace. By 1800, spinning jenny&#8217;s had 80 spinners. And by the 1830&#8217;s the price was 1/20th of the 1700&#8217;s price. </p>
<p>This breakthrough &#8211;mechanized yarn production&#8211; propelled the world into the industrial age, and brought consumers  into expecting constantly improving technology and quality of life. To me the parallels of present day high tech are remarkable, and the &#8220;so what&#8221; factor noteworthy.</p>
<p>Two &#8220;so what&#8221; takeaways:</p>
<ol>
<li><em>The invention of the spinning jenny came because of great bottlenecks in yarn production. </em>In the 1760&#8217;s mostly farmers produced cotton yarn, and this was a cottage industry. When harvest time came the families were far too busy harvesting, and weavers had a great difficulties buying yarn. Often they had to walk six miles each day to gather up enough material for that same day&#8217;s weaving. This bottleneck &#8211;as all bottlenecks&#8211; created a great pressure. A pressure that burst forth in invention, and technological revolution.</li>
<li>In the face of such bottlenecks, Britain sanctioned a contest of which the spinning jenny was an entrant. An example from the past of how using prizes compelled innovation. See the <a href="http://en.wikipedia.org/wiki/X_prize" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">X Prize Foundation</a> for present day contests in medicine, automotive, education, or (Google&#8217;s just announced) <a href="http://en.wikipedia.org/wiki/Google_Lunar_X_PRIZE" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">Lunar X Prize</a>.</li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/JAWspeak?a=sZBLN"><img src="http://feeds.feedburner.com/~f/JAWspeak?i=sZBLN" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/444142838" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2007/10/23/obsess-about-your-time-3-economics-books/feed/</wfw:commentRss>
		<feedburner:origLink>http://jawspeak.com/2007/10/23/obsess-about-your-time-3-economics-books/</feedburner:origLink></item>
		<item>
		<title>Arguing for software testing in difficult environments</title>
		<link>http://feeds.feedburner.com/~r/JAWspeak/~3/444142839/</link>
		<comments>http://jawspeak.com/2007/10/17/arguing-for-software-testing-in-difficult-environments/#comments</comments>
		<pubDate>Wed, 17 Oct 2007 08:02:48 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[testability]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=30</guid>
		<description><![CDATA[I&#8217;m a ThoughtWorker. ThoughtWorks is changing the way that enterprise software is delivered. And with that we take firm stances on heavily debated topics. In previous jobs I&#8217;ve tried to push test driven development, unit testing, code coverage metrics, continuous integration&#8230; all controversial &#8216;best practices&#8217;. Results were mixed.
A few weeks ago I was at a [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a <a href="http://www.thoughtworks.com/what-we-do/what-we-do.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.thoughtworks.com');">ThoughtWorker.</a> ThoughtWorks is changing the way that enterprise software is delivered. And with that we take firm stances on heavily debated topics. In previous jobs I&#8217;ve tried to push test driven development, unit testing, code coverage metrics, continuous integration&#8230; all controversial &#8216;best practices&#8217;. Results were mixed.</p>
<p>A few weeks ago I was at a large web 2.0 social networking site working with <a href="http://seleniumgrid.thoughtworks.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/seleniumgrid.thoughtworks.com');">selenium grid</a> automation. They were great clients, fully receptive to automated testing. Next week I&#8217;ll be heading to another leading internet company to work triage:</p>
<ol>
<li>Work on troubled teams whose code is poorly tested</li>
<li>Enable groups to test legacy code</li>
<li>Attempt to spread a pervasive test driven mindset.</li>
</ol>
<p>I&#8217;m joining a senior team of ThoughtWorkers and in preparation I&#8217;ve thought of various arguments I&#8217;ve heard (or used myself) against testing code. I&#8217;ll be challenged working with these very experienced people, but I am eagerly looking forward to the experience.</p>
<h3>Argument #1</h3>
<p><em>Adding all these tests only makes more code to maintain, debug, and write. This can&#8217;t be good - I want less work, not more!<br />
</em><br />
<em>Rebuttal:</em> Would you agree code and requirements often change? Would it be valuable if something could automatically and accurately catch bugs introduced with changes? How about if the original developers are no longer on the project? Testing can enable less work &#8212; in a dynamically changing environment. Immediately the work is greater, but over time it is less.</p>
<h3>Argument #2</h3>
<p><em>Ok, fair enough, there are some good reasons to do this. BUT, when I want to change something later, I now have two points of failure - the code I&#8217;m changing, and all the tests that depend on that code. I haven&#8217;t really bought myself all that much security, because if my tests don&#8217;t catch the problem well, I&#8217;m just as hosed as if I had no tests. <sup>Source: first comment from <a href="http://www.railsenvy.com/2007/10/4/how-i-learned-to-love-testing-presentation" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.railsenvy.com');">here</a></sup></em><br />
<em>Rebuttal:</em></p>
<ol>
<li>You get better and faster with tests the more you write them.</li>
<li>By writing tests you further understand the business domain and craft a better thought out solution.</li>
<li>Whenever making changes in the future you actually have <em>1 + n</em> points of failure. That which you are changing plus the other interacting systems within the code. By writing tests you will automatically catch the interactions, as well as the initial point of failure. Sure the tests need maintaining, but now with two things to maintain, you catch (almost all) these failure points.</li>
</ol>
<h3>Argument #3</h3>
<p><em>I generally think testing is a good idea. But I&#8217;m stressed out, I&#8217;ll get to it later&#8230; tomorrow I&#8217;ll add tests&#8230; as soon as I get this working</em><br />
Rebuttal: Take a page from <em><a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.com%2FSoftware-Development-Principles-Patterns-Practices%2Fdp%2F0135974445&amp;tag=econtechblog-20&amp;linkCode=ur2&amp;camp=1789&amp;creative=9325" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.amazon.com');">Agile Software Development: Principles, Patterns, and Practices</a> by Robert C. Martin.</em>. He argues for refactoring but since the two concepts are so tightly entwined, I think the argument applies here:</p>
<blockquote><p>&#8220;Refactoring is like cleaning up the kitchen after dinner. The first time you skip it, you are done with dinner more quickly. But that lack of clean dishes and clear working space makes dinner take longer to prepare the next day. This makes you want to skip cleaning again. Indeed, you can always finish dinner faster today if you skip cleaning, but the mess builds and builds. Eventually you are spending an inordinate amount of time hunting for the right cooking utensils, chiseling the encrusted dried food off of the dishes, and scrubbing them down so that they are suitable to cook with. Dinner takes forever. Skipping the cleanup does not really make dinner go faster.&#8221;</p></blockquote>
<p>Skipping testing does not really make software development faster, because changes are guaranteed. (You&#8217;ll have to cook another dinner eventually). Without an easy way to baseline and build upon existing code, time is spent bugfixing that could instead be adding features or writing new tests.</p>
<h3>Argument #4</h3>
<p><em>I&#8217;m awesome.  I don&#8217;t write bugs. So I don&#8217;t need tests.</em><br />
Rebuttal: Great. I&#8217;m excited to be working with you. I&#8217;m sure I&#8217;ll be able to learn a great deal. I imagine you like fresh challenges. And in six months or a year this current project won&#8217;t be as interesting to you as it is today. In fact, you&#8217;ll be on to something more challenging and worthy of your awesomeness.</p>
<p>So that means someone else &#8212; possibly a junior developer &#8212; will be maintaining and working on this code. Without tests, they will be frequently seeking your assistance and guidance to prevent bugs. This is not what you want, is it? You want new challenges, not constantly being hassled by old code. So write the tests now to ensure your ego and intellect can move forward to bigger and better things.</p>
<p>Elaborating and paraphrasing, Neal Ford argued at eRubycon 2007:</p>
<blockquote><p>Now I look at <em>not testing</em> as professionally <em>irresponsible.</em> I&#8217;m paid to create software, to deliver on a client&#8217;s business needs. If I don&#8217;t rigorously and automatically ensure I have accomplished this with the minimum amount of bugs &#8212; I am committing malpractice.</p></blockquote>
<p>What arguments have you encountered, and how have you responded?</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/JAWspeak?a=zOMRN"><img src="http://feeds.feedburner.com/~f/JAWspeak?i=zOMRN" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/444142839" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2007/10/17/arguing-for-software-testing-in-difficult-environments/feed/</wfw:commentRss>
		<feedburner:origLink>http://jawspeak.com/2007/10/17/arguing-for-software-testing-in-difficult-environments/</feedburner:origLink></item>
		<item>
		<title>Chicago to San Francisco, by way of India</title>
		<link>http://feeds.feedburner.com/~r/JAWspeak/~3/444153331/</link>
		<comments>http://jawspeak.com/2007/08/10/chicago-to-san-francisco-by-way-of-india/#comments</comments>
		<pubDate>Fri, 10 Aug 2007 08:04:07 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[thoughtworks]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=34</guid>
		<description><![CDATA[I&#8217;ve really, really missed the really smart people I used to work with.
I believe working full time, with great people, and doing my own projects on the side  will be vastly more productive than having full time for my own projects.
After leaving FeedBurner with the Google acquisition, I gave myself 2 months of running [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm1.static.flickr.com/3/3823677_6d67417d50_m.jpg" align="right" />I&#8217;ve really, really missed the <a href="http://www.burningdoor.com/eric/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.burningdoor.com');">really</a> <a href="http://www.ericjohnolson.com/blog/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ericjohnolson.com');">smart</a> <a href="http://johnzeratsky.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/johnzeratsky.com');">people</a> I used to work with.</p>
<p>I believe working full time, with great people, and doing my own projects on the side  will be vastly more productive than having full time for my own projects.</p>
<p>After leaving FeedBurner with the <a href="http://www.feedburner.com/google" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.feedburner.com');">Google acquisition</a>, I gave myself 2 months of running my own business full time. After that period, I would either be hiring folks, giving myself a few more months, or getting more experience at a startup or consulting.</p>
<p>Second Valley&#8217;s revenues are up a healthy 25-40% compared to May. I&#8217;ve been spending time in Ruby on Rails, and have started rebuilding the full ecommerce and delivery platform for one of Second Valley&#8217;s sites. But I missed the smart coworkers.</p>
<p>My decision Wednesday was to email <a href="http://www.thoughtworks.com/work-for-us/work-for-us.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.thoughtworks.com');">ThoughtWorks</a> and continue my interview process I started prior to joining FeedBurner. Well, thanks to the amazing Carrie McComb, I interviewed Thursday and had an informal offer that night. Friday morning I signed and it&#8217;s official.</p>
<p><img src="http://photos1.blogger.com/img/135/5613/400/may%2018%20M%20G%20road%20area%20022.jpg" width="200" align='right' /><br />
In 10 days I&#8217;ll be off to India for <a href="http://www.thoughtworks.com/work-for-us/training.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.thoughtworks.com');">ThoughtWorks Immersion</a> training, and then I&#8217;m relocating to <a href="http://maps.google.com/maps?f=q&#038;hl=en&#038;q=410+Townsend+Street,+san+francisco&#038;layer=&#038;sll=41.8845,-87.622257&#038;sspn=0.009234,0.023088&#038;ie=UTF8&#038;z=16&#038;om=1&#038;iwloc=addr" onclick="javascript:pageTracker._trackPageview('/outbound/article/maps.google.com');">San Francisco</a>.</p>
<p><small>Photo credits: <a href="http://www.flickr.com/photos/meaux/3823677/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.flickr.com');">meaux</a>, and <a href="http://artview.blogspot.com/2005_05_01_archive.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/artview.blogspot.com');">artview</a> (my previous trip to India)</small></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/JAWspeak?a=22G3N"><img src="http://feeds.feedburner.com/~f/JAWspeak?i=22G3N" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/444153331" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2007/08/10/chicago-to-san-francisco-by-way-of-india/feed/</wfw:commentRss>
		<feedburner:origLink>http://jawspeak.com/2007/08/10/chicago-to-san-francisco-by-way-of-india/</feedburner:origLink></item>
		<item>
		<title>Learning Experiences! TSG to FeedBurner (until Google) to my startup, Second Valley, Inc</title>
		<link>http://feeds.feedburner.com/~r/JAWspeak/~3/444153332/</link>
		<comments>http://jawspeak.com/2007/07/07/learning-experiences-tsg-to-feedburner-until-google-to-my-startup-second-valley-inc/#comments</comments>
		<pubDate>Sat, 07 Jul 2007 08:12:10 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[startup]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=36</guid>
		<description><![CDATA[
Yes, I am well. 

I left the botique enterprise content management software consulting company, Technology Services Group. [1]
I joined FeedBurner, as an engineer in February.
I did some really cool ad serving optimization code. My IE degree let me do some fun multivariate linear regressions to prioritize ad serving into their feed ad network. The code [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/35712969@N00/1073849657/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.flickr.com');" title="Photo Sharing"><img src="http://farm2.static.flickr.com/1375/1073849657_2a810c5380_m.jpg" width="240" height="180" alt="jaw" align='right'/></a><br />
Yes, I am well. </p>
<ol>
<li>I left the botique enterprise content management software consulting company, <a href="http://tsgrp.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/tsgrp.com');">Technology Services Group</a>. <sup>[1]</sup></li>
<li>I joined <a href="http://feedburner.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/feedburner.com');">FeedBurner</a>, as an engineer in February.</li>
<li>I did some really cool ad serving optimization code. My <a href="https://engineering.purdue.edu/IE/" onclick="javascript:pageTracker._trackPageview('/outbound/article/engineering.purdue.edu');">IE</a> degree let me do some fun multivariate linear regressions to prioritize ad serving into their <a href="http://www.feedburner.com/fb/a/advertising" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.feedburner.com');">feed ad network</a>. The code base was great to work in. Plus the team was great and I&#8217;ll really miss them. This leads to #4.</li>
<li>Thanks to the Chicago PHP users&#8217; group, as well as my <a href="http://techsocial.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/techsocial.com');">Chicago tech event calendar site Techsocial</a>, I was able to attend php|tek. The <a href="http://hades.phparch.com/ceres/public/tek/live/index.php/tek_live::slides" onclick="javascript:pageTracker._trackPageview('/outbound/article/hades.phparch.com');">presentations</a> are now available. <sup>[2]</sup></li>
<li>Google acquired FeedBurner in July. I don&#8217;t have much to say here, other than I learned a <em>ton</em> living through the acquisition process.</li>
<li>Meanwhile, I incorporated a side business that I&#8217;ve been working on since 2003. It&#8217;s been profitable since the launch in September &#8216;06. The entity is Second Valley, Inc, but I&#8221;m operating under <a href="http://en.wikipedia.org/wiki/Doing_business_as" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">another name</a>. <sup>[3]</sup></li>
<li>I pretty much had the perfect opportunity to ramp up my business by working on it full time. I&#8217;ll spend a few months at marketing, product development, (more) SEO, statistical analysis enhancements, and rebuilding the PHP app in Ruby on Rails.</li>
</ol>
<p><small>Notes:</p>
<ol>
<li>This is where I started my career and if any of you reading this are college students interviewing with TSG, feel free to contact me. Because of the small size, and management style, if you&#8217;re aggressive you can get 3 years of experience in 18 months. I went from zero to supervising another developer and working directly with clients on $200K and $300K+ projects. Plus the people are really fun!</li>
<li>I&#8217;ve spent most of my time in Java, but up until now all my side projects were in php. The <a href="mailto:http://tekrat.com/wp/talks/phptek2007/apc@facebook.pdf" onclick="javascript:pageTracker._trackPageview('/outbound/article/tekrat.com');">Facebook APC presentation</a> was killer!</li>
<li>Last year at <a href="http://2006.barcampchicago.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/2006.barcampchicago.com');">Bar Camp Chicago</a> a bunch of us tried to get <a href="http://chicagocoworking.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/chicagocoworking.com');">Chicago Coworking</a> up and running. That never took off, but one of the name ideas was Second Valley (You know, create an entrepreneur friendly community like Silicon Valley. Call it&#8230; Second Valley. Which is even a bigger pun when you think of Chicago&#8217;s <a href="http://secondcity.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/secondcity.com');">Second City</a>.) <em>My</em> business is unrelated to coworking, but I had the domain, and it can hold multiple doing-business-as projects, so I figured <a href="http://en.wikipedia.org/wiki/Principle_of_good_enough" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">it&#8217;s good enough</a>.</li>
</ol>
<p></small></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/JAWspeak?a=hnWJN"><img src="http://feeds.feedburner.com/~f/JAWspeak?i=hnWJN" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/444153332" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2007/07/07/learning-experiences-tsg-to-feedburner-until-google-to-my-startup-second-valley-inc/feed/</wfw:commentRss>
		<feedburner:origLink>http://jawspeak.com/2007/07/07/learning-experiences-tsg-to-feedburner-until-google-to-my-startup-second-valley-inc/</feedburner:origLink></item>
		<item>
		<title>First Steps in Rails, RESTful by Example, Part 1: Beast</title>
		<link>http://feeds.feedburner.com/~r/JAWspeak/~3/444142840/</link>
		<comments>http://jawspeak.com/2007/07/04/first-steps-in-rails-restful-by-example-part-1-beast/#comments</comments>
		<pubDate>Wed, 04 Jul 2007 08:00:51 +0000</pubDate>
		<dc:creator>Jonathan</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://jawspeak.com/?p=27</guid>
		<description><![CDATA[I&#8217;m migrating one of my main e-commerce sites from php to Rails. Coming from a few years of Java and php makes me really appreciate this framework&#8217;s rapid development cycles, as well as strict MVC approach.
Note: this is a technical post, it assumes you&#8217;re interested in, and familiar with Rails.
Rails wants to be RESTful. Many [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m migrating one of my main e-commerce sites from php to Rails. Coming from a few years of Java and php makes me really appreciate this framework&#8217;s rapid development cycles, as well as strict MVC approach.</p>
<blockquote><p>Note: this is a technical post, it assumes you&#8217;re interested in, and familiar with Rails.</p></blockquote>
<p>Rails wants to be RESTful. Many <a href="http://peepcode.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/peepcode.com');">sites</a> and <a href="http://www.pragmaticprogrammer.com/titles/rails/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.pragmaticprogrammer.com');">books</a> go into depth explaining REST. Last year&#8217;s Railsconf keynote by <a href="http://loudthinking.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/loudthinking.com');">DHH</a> can give you the big picture of CRUD and RESTful applications. (Be sure to follow along with the <a href="http://downloads.scribemedia.net/rails2006/worldofresources.pdf" onclick="javascript:pageTracker._trackPageview('/outbound/article/downloads.scribemedia.net');">pdf slides</a>, while you <a href="http://www.scribemedia.org/2006/07/09/dhh/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.scribemedia.org');">watch the video</a>).</p>
<h3>Look at an existing mature project (Beast) to learn how to make RESTful models</h3>
<p>Nitty gritty RESTful implementation details have been hard to find. So I started searching out open source projects that are known for good design. And I read the code.</p>
<p><a href="http://beast.caboo.se/" onclick="javascript:pageTracker._trackPageview('/outbound/article/beast.caboo.se');">Beast</a> is a forum program written in Rails by <a href="http://weblog.techno-weenie.net/" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblog.techno-weenie.net');">Rick Olson</a> and <a href="http://www.workingwithrails.com/person/5337-josh-goebel" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.workingwithrails.com');">Josh Goebel</a>. Best of all, it&#8217;s a great example of a REST application.</p>
<p>I&#8217;m a visual person, so I created the chart below to help me get the hang of what the Models and relationships look like in Beast. Big bold squares are actual database backed objects. Dotted squares are just regular models.</p>
<p><a href="http://www.flickr.com/photos/35712969@N00/722545282/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.flickr.com');" title="Photo Sharing"><img src="http://farm2.static.flickr.com/1277/722545282_c70a817b6c.jpg" width="376" height="500" alt="Beast Restful Model Diagrams" /></a><br />
Please contact me if you catch an error or omission.</p>
<h3>Here&#8217;s how you use the diagram</h3>
<p>Right now, browse here: <a href="http://svn.techno-weenie.net/projects/beast/trunk/app/models" onclick="javascript:pageTracker._trackPageview('/outbound/article/svn.techno-weenie.net');">http://svn.techno-weenie.net/projects/beast/trunk/app/models</a> to the Subversion source of Beast. Back already? My you&#8217;re fast. Read over the different model objects. See how they relate. Think about what&#8217;s been abstracted into additional Resources, rather than creating actions willy nilly in the controllers.</p>
<p>Then check it out and run it in your local environment. Even if you couldn&#8217;t care less about the (quite nice) forum software that it is, it&#8217;s good to learn by taking it for a spin.</p>
<h3>But I think I need more actions than CRUD gives me!</h3>
<p>As DHH said in the <a href="http://www.scribemedia.org/2006/07/09/dhh/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.scribemedia.org');">2006 Railsconf keynote</a>, sometimes you think you need another non-CRUD verb to your controller. Say you have a Forum that has Users and Topics. Some users want to monitor topics. At first blush, you may want to add an action to Topic. You&#8217;d then post to /topic/monitor/123 to start monitoring topic 123.</p>
<p>There is another way.</p>
<p>Relationships, events and states can all be models. When a new topic is to be monitored, you&#8217;ll GET to /monitorships/new to get the new Monitorship object form. Then POST to /monitorships to actually create it. </p>
<p>Models are more than things.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/JAWspeak?a=jbiwN"><img src="http://feeds.feedburner.com/~f/JAWspeak?i=jbiwN" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JAWspeak/~4/444142840" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jawspeak.com/2007/07/04/first-steps-in-rails-restful-by-example-part-1-beast/feed/</wfw:commentRss>
		<feedburner:origLink>http://jawspeak.com/2007/07/04/first-steps-in-rails-restful-by-example-part-1-beast/</feedburner:origLink></item>
	<media:rating>nonadult</media:rating></channel>
</rss>
