<?xml version="1.0" encoding="UTF-8"?><!-- generator="WordPress/2.9.1" -->
<rss version="0.92">
<channel>
	<title>Jeff's Musings</title>
	<link>http://blog.jeffshurts.com</link>
	<description>Observations and accumulated wisdom</description>
	<lastBuildDate>Tue, 03 May 2011 21:11:01 +0000</lastBuildDate>
	<docs>http://backend.userland.com/rss092</docs>
	<language>en</language>
	
	<item>
		<title>Small, Powerful Teams</title>
		<description><![CDATA[Seymour Cray once said, "If you were plowing a field, which would you rather use? Two strong oxen or 1024 chickens?"  He was making an analogy, of course, to his super-fast processors.  I think the same idea applies to software development teams.]]></description>
		<link>http://blog.jeffshurts.com/2011/03/the-magic-of-leveraging-talent/</link>
			</item>
	<item>
		<title>Ruby on Rails:  Serious Software?</title>
		<description><![CDATA[Ruby on Rails?  For corporate apps, with lots of users, complex business logic and lots of transactions to process?  Uh, yeah...]]></description>
		<link>http://blog.jeffshurts.com/2011/03/ruby-on-rails-serious-software/</link>
			</item>
	<item>
		<title>A little Groovy magic &#8211; Lists and Property Accessors</title>
		<description><![CDATA[<p>Dynamic languages like Groovy and Ruby are all about productivity.  Not only do they eliminate the need to write tons of boilerplate code, they also contain all sorts of &#8220;syntactic sugar&#8221; &#8211; language features that let you accomplish a tremendous amount of work with very little code.</p>
<p>Most of these features &#8211; closures, ultra-convenient collection-oriented operators like the spread-dot (*.), etc., are well-documented.  Some, however, are a bit more arcane, and not realizing they exist can actually cost you a lot of time if you stumble into them inadvertently.</p>
<p>The feature I have in mind at the moment is a very convenient but somewhat surprising bit of collection behavior in Groovy.  I&#8217;ve been working with the language for quite a while, and have dutifully pored over books and language reference documents to become familiar with all of the groovy goodness at my disposal, but somehow I missed this one until someone on my project team found it &#8211; quite by accident.</p>
<p>Here&#8217;s the magic find.  In Groovy, if you have a list of objects, you can access, <em>on the list itself</em>, properties that belong to objects within the list.  The result, somewhat intuitively (but somehow quizzical at the same time), is a list of values of that property across all the members in the list.  Here&#8217;s an example to illustrate what I mean &#8211; just copy this and run it as a Groovy script.</p>
<pre class="brush: groovy;">
class Player {
def name
def teams

public String toString() {
&quot;${name} - played for ${teams}&quot;
}
}

def players =
[
new Player(name: &quot;Greg Maddux&quot;, teams: [&quot;Cubs&quot;, &quot;Braves&quot;]),
new Player(name: &quot;Ron Santo&quot;, teams: [&quot;Cubs&quot;, &quot;White Sox&quot;]),
new Player(name: &quot;Billy Williams&quot;, teams: [&quot;Cubs&quot;, &quot;Athletics&quot;]),
new Player(name: &quot;Bruce Sutter&quot;, teams: [&quot;Cubs&quot;, &quot;Cardinals&quot;]),
new Player(name: &quot;Lou Brock&quot;, teams: [&quot;Cubs&quot;, &quot;Cardinals&quot;]),
new Player(name: &quot;Gary Gaetti&quot;, teams: [&quot;Twins&quot;, &quot;Cubs&quot;]),
new Player(name: &quot;Ron Cey&quot;, teams: [&quot;Dodgers&quot;, &quot;Cubs&quot;]),
new Player(name: &quot;Ryne Sandberg&quot;, teams: [&quot;Cubs&quot;]),
new Player(name: &quot;Mark Grace&quot;, teams: [&quot;Cubs&quot;, &quot;Diamondbacks&quot;]),
new Player(name: &quot;Goose Gossage&quot;, teams: [&quot;Athletics&quot;, &quot;Yankees&quot;, &quot;Cubs&quot;]),
new Player(name: &quot;Sammy Sosa&quot;, teams: [&quot;Rangers&quot;, &quot;White Sox&quot;, &quot;Cubs&quot;]),
new Player(name: &quot;Larry Bowa&quot;, teams: [&quot;Phillies&quot;, &quot;Cubs&quot;]),
new Player(name: &quot;Rick Monday&quot;, teams: [&quot;Dodgers&quot;, &quot;Cubs&quot;]),
new Player(name: &quot;Dave Kingman&quot;, teams: [&quot;Rangers&quot;, &quot;Mets&quot;, &quot;Cubs&quot;]),
new Player(name: &quot;Joe Girardi&quot;, teams: [&quot;Cubs&quot;, &quot;Cardinals&quot;, &quot;Yankees&quot;])
]

def playerNames = players.name
println &quot;Here, amazingly enough, is a list containing the names of all those players:\n $(playerNames)&quot;
</pre>
<p>Once you know this behavior exists, it&#8217;s pretty easy to find situations where it&#8217;s an insanely convenient feature.  If you don&#8217;t know it exists, you can get some pretty confusing results.  In our case, we were running a GORM query to retrieve a domain object using an alternate ID (expecting a single result), and incorrectly used the <code>list()</code> method (we should have used <code>get()</code>, which returns the domain object, whereas <code>list()</code> always returns a list).</p>
<p>In our code, after querying for the domain object, we accessed properties of the object, and were puzzled when instead of getting Strings and Integers and Dates, we were getting single-member <em>lists</em> of Strings and Integers and Dates.  Each list <code>contained</code> the value we expected, inexplicably embedded in a List instance.  It took a little head-scratching before we figured out that the root cause was that our query was returning a list containing our domain object, and our code that accessed the properties, which would have failed miserably in Java if attempting to treat a List as though it were a domain object, was happily drilling through the wall of that list and getting at its contents.</p>
<p>Syntactic sugar?  Definitely.  Violation of the principle of least surprise?  Maybe.  Will I use it, now that I know it&#8217;s a tool at my disposal?  Absolutely.</p>
<p>Stay Groovy, my friends&#8230;</p>
]]></description>
		<link>http://blog.jeffshurts.com/2010/05/a-little-groovy-magic-lists-and-property-accessors/</link>
			</item>
	<item>
		<title>Grails Pagination and CriteriaBuilder</title>
		<description><![CDATA[A colleague of mine and I have agreed on an analogy for Grails development:  it’s like driving on the Autobahn, with serious sets of speed bumps every few miles.  One minute you’re flying along in hyper-productivity mode, and the next you’re inching along - digging through reference docs and forums trying to figure out why some little feature isn’t working.

My most recent speed bump is one that’s likely to appear in front of just about every Grails developer - getting pagination working with a result set generated by CriteriaBuilder - so I figured I’d help everyone join me in putting it in the rearview mirror.]]></description>
		<link>http://blog.jeffshurts.com/2010/04/grails-pagination-and-criteriabuilder/</link>
			</item>
	<item>
		<title>Using Grails Controller Interceptors To Avoid Rampant Testing</title>
		<description><![CDATA[<p>Test-driven development and the resulting test coverage it affords are some of the most important benefits of modern development practices.  When it comes time to refactor code or make a significant functional change, there’s nothing like the peace of mind afforded by a comprehensive set of well-written unit tests all emitting that wonderful emerald green.</p>
<p>But such peace of mind comes at a cost.  I’ve heard estimates from various teams I’ve talked to stating that the cost of writing unit tests for adequate code coverage (usually 50% to 80% on Java projects) can range from equivalent to the production code itself, to five times that.  The problem with these estimates, of course, is subjectivity.  For example, if you have found a bug using a test and work to fix the test, are you mentally counting that time as test-writing or code-writing?</p>
<p>Estimating factors aside, the plain fact is that testing does amplify the cost of software development – at least in the short term.  Which means that a software engineer who really cares about his customer’s bottom line should always be on the lookout for ways to avoid the increased cost of testing.</p>
<p>This line of thinking arose the other day on the project I’m currently working on.  It’s a Groovy/Grails web application with some public, customer-facing components and some internal-use components.  We’re using Grails scaffolding as much as is practical for the relatively infrequently-used internal-use features to save time and money.  In most cases, we have generated and tweaked the UI components (GSP pages) to smooth over some of the uglier bits of scaffolded pages, but we have tried not to generate any of the controller code, instead relying on Grails’ generate-at-runtime approach by including <code>def scaffold = true</code> in these controllers.</p>
<p>Why not generate the source?  Because generated code is deceptively expensive!  The minute a feature springs into  existence in your code base, it needs to be tested – even if that code was generated by a framework like Grails.  And Grails controller closures – <code>insert</code> and <code>update</code>, as the case in point here, do a significant amount work for you.  Data binding.  Optimistic locking exception handling.  Routing of validation errors.  All things that “just work” in scaffolded code, but which might be broken by someone once the code actually becomes part of your code base.</p>
<p>So when the need arose to customize part of the logic in insert and update closures (to do some custom interpretation of a series of check boxes on a form that couldn’t be made to conform to the default binding mechanism), we began looking for ways to override binding logic without generating and modifying the closures themselves.</p>
<p>As usual, Grails has a solution at the ready – controller <a href="http://www.grails.org/Controllers+-+Interceptors">interceptors</a>.  All we had to do was declare an interceptor that fires before insert and update closures, and in that closure, inspect our list of check boxes and set a <code>params</code> value that would then be assigned to our domain object through the normal binding process.</p>
<p>By using an interceptor, we completely avoided the need to generate (and assume custodianship of) the <code>insert</code> and <code>update</code> closures in this controller – which means we didn’t have to spend valuable time writing unit tests to cover these Grails-supplied features that could be broken once the code actually exists. </p>
<p>I guess I can summarize this little victory this way:  Having tested code for an application feature is far better than having untested code.  Having no code at all is better than either.  </p>
<p>Stay Groovy, my friends.</p>
]]></description>
		<link>http://blog.jeffshurts.com/2010/04/using-grails-controller-interceptors-to-avoid-rampant-testing/</link>
			</item>
	<item>
		<title>All-Time Favorite Instrumental Tracks</title>
		<description><![CDATA[I’ve been meaning to put together a list of my favorite all-instrumental recordings for some time now, and finally found some time to get it done.  I’ve heard a lot of acoustic music over the years, and the list below represents my personal highlight reel.]]></description>
		<link>http://blog.jeffshurts.com/2010/03/all-time-favorite-instrumental-tracks/</link>
			</item>
	<item>
		<title>Elegant Design, Customer Service:  It&#8217;s In the Details</title>
		<description><![CDATA[<p>I recently purchased an Apple bluetooth keyboard and Magic Mouse for my Mac Mini (which I bought with the intention of using as a home theater media hub, but which gets almost as much use for &#8216;normal&#8217; computer tasks).</p>
<p>When I first started test driving the Magic Mouse, I happened to be in iTunes, and happened to need to adjust the volume &#8211; which is a horizontal slider in the UI.  I thought to myself, &#8220;This mouse has the ability to do scrolling in any direction &#8211; I wonder what happens if I hover over the volume control and swipe right?&#8221;  Bam.  Of course it worked.  It&#8217;s Apple, and they think of *everything.*</p>
<p>I was truly impressed.  And, being an engineer and naturally inquisitive, I took notice that I was impressed &#8211; particularly by such a &#8220;little thing.&#8221;  I then realized that I was impressed not <em>despite</em> the fact that this was a little thing, but <em>because</em> it was a little thing.  The sort of thing that other user interface and hardware designers might well have missed.</p>
<p>Which brings me to the moral of this story.  I work in a consulting firm, and our goal is not merely to meet our customers&#8217; expectations, but to surpass them.  In short, to <em>impress</em> them.  I think that sometimes we find this hard to do.  We need to remind ourselves that sometimes it&#8217;s just the little things we do &#8211; things that others might have missed &#8211; that will make the biggest impression.</p>
]]></description>
		<link>http://blog.jeffshurts.com/2010/02/elegant-design-customer-service-its-in-the-details/</link>
			</item>
	<item>
		<title>I&#8217;ve looked at clouds from both sides now&#8230;</title>
		<description><![CDATA[<p>I stumbled across a very cool cloud-based music service called <a title="SoundCloud" href="http://www.soundcloud.com" target="_blank">SoundCloud</a> (http://www.soundcloud.com) today.  I love it for two very different reasons.  First, it&#8217;s a great (maybe even killer) application of cloud computing technology, taking advantage of the Great Server Farm In the Sky to solve a real problem.  Second, I love the solution itself.</p>
<p>See, technology is my day job.  When I&#8217;m not working (or walking the dog, or schlepping kids around town), I usually have some sort of musical instrument in my hands. or in front of me. Guitar, mandolin, bass, keyboards, drums and trumpet, for now.  Hope to add to the collection soon &#8211; I think I need a bouzouki.  Or maybe a dobro.  But I digress&#8230;</p>
<p>When I have a block of free time and a little peace and quite in the house, I like to break out my recording gear and see what I can throw together.  And, occasionally, share it with a few friends to see what they think.  Or even send a track to a friend who&#8217;s a <em>real</em> drummer to lay down a drum track for me to mix in later.</p>
<p>In the past, sharing music online has been inconvenient at best.  Oh, there are music sharing sites like <a title="SoundClick" href="http://www.soundclick.com" target="_blank">SoundClick</a>, or social sites like <a title="MySpace" href="http://www.myspace.com" target="_blank">MySpace</a> that cater to musicians.  But they all have some pretty serious limitations (like having to actually log into their service to find and listen to tracks).</p>
<p>SoundCloud is different.  It&#8217;s a <strong>seriously </strong>open, cloud-based music storage and publishing service.  I just signed up an hour ago, and within minutes I was uploading my first track.  (I love, by the way, that you specify the file to upload first, and it <em>automatically </em>starts uploading while you fill in the track info form.)</p>
<p>But the really cool part is the openness of the service.  There&#8217;s no need for anyone to go to their site to hear my music.  I can email it to them, or drop a widget into Facebook or a blog entry (as I&#8217;ve done here), and voila.  Music.  Where I want it.  No strings attached.</p>
<p>And now, if you&#8217;ll excuse me, I have a recording project to dive into&#8230;</p>
<div style="font-size: 11px;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="100%" height="81" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowscriptaccess" value="always" /><param name="src" value="http://player.soundcloud.com/player.swf?track=illinois-river-rag&amp;show_comments=true&amp;auto_play=false&amp;color=aa2f3b" /><embed type="application/x-shockwave-flash" width="100%" height="81" src="http://player.soundcloud.com/player.swf?track=illinois-river-rag&amp;show_comments=true&amp;auto_play=false&amp;color=aa2f3b" allowscriptaccess="always"></embed></object></p>
<div style="padding-top: 5px;"><a href="http://soundcloud.com/jeffshurts/illinois-river-rag">Illinois River Rag</a> by  <a href="http://soundcloud.com/jeffshurts">JeffShurts</a></div>
</div>
]]></description>
		<link>http://blog.jeffshurts.com/2009/07/ive-looked-at-clouds-from-both-sides-now/</link>
			</item>
	<item>
		<title>On Shimmer and Patience</title>
		<description><![CDATA[<p><!--[endif]--></p>
<p class="MsoNormal">Remember <em>Shimmer</em> on Saturday Night Live?<span> </span>Dan Aykroyd and Gilda Radner?<span> </span>“It’s a dessert topping <em>and</em> a floor wax!”<span> </span>If you’re as old as I am or enough of an SNL fan to have caught that old episode on DVD, you’re probably chuckling a little.<span> </span>Humor has many triggers in the human brain, and absurdity is certainly one of them.</p>
<p class="MsoNormal">That’s why my initial reaction to something that happened at work the other day was to laugh – a reaction which, thankfully, I was successful in suppressing.<span> </span>Not only because laughing would<span> </span>have been unprofessional, but because, as is often the case, my first impression was superficial and, ultimately, off the mark.</p>
<p class="MsoNormal">The topic of discussion was the Continuous Integration build at a client.<span> </span>Let’s see if I can recreate the scene.<span> </span>Names, of course, have been changed to protect those who may not want their names to appear here…</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span>I see that there are 800-odd unit tests in our code base, and I can run them locally, but the CI build only runs 150 or so of them.<span> </span>Is something wrong?</p>
<p class="MsoNormal"><strong>Bob the Builder:<span> </span></strong>No, this is correct.</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span>Come again?</p>
<p class="MsoNormal"><strong>Bob the Builder:<span> </span></strong>Yes, we do this intentionally.</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span>Okay, I have to ask.<span> </span>Why?<span> </span>Does it take too long to run all of the tests?</p>
<p class="MsoNormal"><strong>Bob the Builder:<span> </span></strong>No, not really.<span> </span>The build with all the tests runs in 10 minutes or so.</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span>Then why do we run a just a subset of them on code checkin?</p>
<p class="MsoNormal"><strong>Bob the Builder:<span> </span></strong>Well, we run the full set of tests in a different build that runs nightly.</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span>Hmm&#8230;<span> </span>Doesn’t running the tests at night make it difficult to track down whose code submission is responsible for tests that start failing?<span> </span>And doesn’t it remove the benefit of immediate feedback?<span> </span>I’m getting on in years, and sometimes I get to work in the morning not remembering a lot about what I did the night before.</p>
<p class="MsoNormal"><strong>Bob the Builder:<span> </span></strong>I see your point.<span> </span>It would be a lot better if we ran the full set of tests all the time, on every code check-in.</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span>Great.<span> </span>So you’ll make the necessary changes to the build script?</p>
<p class="MsoNormal"><strong>Bob the Builder: </strong><span> </span>No, I can’t do that.</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span>Wonderful, thanks… wait – did you just say “No?”</p>
<p class="MsoNormal"><strong>Bob the Builder: </strong><span> </span>Correct.<span> </span>I can’t change the build.</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span>Okay, I have to ask.<span> </span>Why not?</p>
<p class="MsoNormal"><strong>Bob the Builder: </strong><span> </span>Because we don’t want this build to fail.</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span><em>(This is about the point where I had to start physically suppressing laughter)</em><span> </span>But the build is <em>supposed</em> to fail if there are broken tests.<span> </span>That’s how we know there’s something that needs to be fixed, and who’s responsible – er, best qualified to fix it.</p>
<p class="MsoNormal"><strong>Bob the Builder: </strong><span> </span>Right, I understand that.<span> </span>But the jars we produce in this build get deployed in an overnight process.<span> </span>So we don’t want the build to fail, because if it does, the daily build won’t get deployed.</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span>Okay, I see that.<span> </span>But why do you <em>want</em> to deploy a build that you know has bugs in it?<span> </span>Or, in this case, that <em>might</em> have bugs in it, since you’re not running all of the tests…</p>
<p class="MsoNormal"><strong>Bob the Builder: </strong><span> </span>Well, the deployment isn’t just for this team.<span> </span>There’s another team on the East Coast that needs that build to be deployed every day.</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span>Hmm… interesting.<span> </span>Are the tests we’re not running <em>our</em> tests or <em>theirs</em>?</p>
<p class="MsoNormal"><strong>Bob the Builder: </strong><span> </span>Mostly ours, I think.<span> </span>But it doesn’t matter – we can’t let broken tests stop the deployment, because usually only a small number of features are affected by those tests, and lots of people need to see the deployed application the next day in our demo environment.</p>
<p class="MsoNormal"><strong>Jeff the Consultant:</strong><span> </span>Okay, that makes sense – I guess.<span> </span>But isn’t there another way to do this?<span> </span>For example, couldn’t we run the full suite of unit tests at code check-in time, and make the <em>nightly</em> build the one that skips tests and reliably produces the demo jar files?<span> </span>That way at least we’d get back the benefit of immediate feedback and have a better idea whose code is causing a test to start failing.</p>
<p class="MsoNormal"><strong>Bob the Builder: </strong><span> </span>I think we could do that.<span> </span>But I don’t have time to dig into an overhaul of the build process, because I have development responsibilities too, and we’re only 2 days from code freeze.</p>
<p class="MsoNormal"><em>(Exit cubicle, stage right…)</em></p>
<p class="MsoNormal">By this time my head was spinning.<span> </span>I wasn’t sure whether what I’d just heard made sense, or whether I’d just been had.<span> </span>I was pretty sure the whole build arrangement they had settled on was crazy, but I could also see how an organization could have evolved into this arrangement because of conflicting needs.</p>
<p class="MsoNormal">The root of their problem is the Shimmer conundrum.<span> </span>It’s neither a dessert topping nor a floor wax, but their CI build is certainly trying to be two very different things at the same time.<span> </span>It was probably started as a CI build in the Agile sense, with the primary purpose being immediate feedback in the form of unit test results.<span> </span></p>
<p class="MsoNormal">But of course, like any build, it also <em>builds something.</em><span> </span>Those jar files were ripe for the picking, and some enterprising person had the great idea to deploy them every day so interested parties in the company would be able to see the application “fresh from the oven” – with all of the evolving new features on display.</p>
<p class="MsoNormal">The problem is that the secondary purpose of this particular build – generation of compiled, deployable software, became more critical to <em>somebody</em> – some person with influence – and the build began to slowly stop meeting its initial purpose.</p>
<p class="MsoNormal">So, is there a point to this rambling blog post?<span> </span>Indeed there is.<span> </span>It’s a word of caution to those of us in the consulting profession.<span> </span>It’s very easy for those of us who spend a lot of time reading and in other ways learning about “ideal” situations – such as well-run Agile projects – to become easily frustrated when we encounter things that are in some way less than ideal.<span> </span>We have to remember to suspend judgment long enough to understand the big picture – all of the various problems our clients are trying to juggle – and then offer our assistance in helping improve things, at a pace that makes sense in their environment.</p>
<p class="MsoNormal">I’ll try to remember this myself as I return to work tomorrow…</p>
]]></description>
		<link>http://blog.jeffshurts.com/2009/04/on-shimmer-and-patience/</link>
			</item>
	<item>
		<title>Of Entities and Identities</title>
		<description><![CDATA[<p>I really like Hibernate.  Sure, it can be frustrating at times, the learning curve can be steep, and some of the exceptions you get when you do stupid things aren&#8217;t all that helpful.  But the fact that it&#8217;s frustrating and hard to learn are manifestations of the fact that it&#8217;s tackling some really thorny problems.  And the cryptic-exception issue does get a little better with each release.</p>
<p>There is one thing, however, that has bothered me since I started using Hibernate several years ago.  A deep bother.  Not a &#8220;this is a nuisance, but I can live with it&#8221; bother, but more of a &#8220;this is so fundamental an issue that there just <em><strong>has </strong></em>to be a better solution to it than is being offered by Hibernate&#8217;s authors&#8221; bother.</p>
<p>The problem:  bridging the gap between object identity and database identity.  In most modern database schemas, tables are defined with a numeric primary key column, which is populated through some unique key assignment mechanism (Identity columns in SQL Server or MySQL, sequences in Oracle, etc).</p>
<p>This works great at the database layer.  But problems arise in the JVM (or CLR for you NHibernate folks).  In order for objects representing database entities (those managed by Hibernate) to be handled properly in collections (including Hibernate cache), objects that have the same database identity need to be recognized as equals as well.  In Java, this means overriding equals() and hashCode() such that any two objects that represent the same database entity will be equal, and return the same hash code.</p>
<p>The &#8220;obvious&#8221; solution, at first blush, would be to base <strong>equals() </strong>and <strong>hashCode()</strong> on entity ID values.  This works great for entities <em>created </em>by Hibernate, which represent existing rows in a database, all with unique ID&#8217;s.  The problem has to do with <em>new</em> entites that you create programmatically, which haven&#8217;t yet been saved.  Those entities will typically have a <em>null</em> ID value &#8211; and if you base equality on ID values, any two unsaved instances will be considered equal.</p>
<p>There are actually two problems when dealing with unsaved entity objects.  The first, as stated above, is that they don&#8217;t yet have a unique identity &#8211; so multiple new instances will collide in collections like Maps and Sets.  The other problem is that the identity of these objects <em>will be set at some point</em>, which violates part of the contract of <strong>hashCode()</strong> &#8211; the part that says its value must not mutate over time.</p>
<p>To avoid all of thes problems, Hibernate&#8217;s authors have long recommended a workaround &#8211; use &#8220;natural keys&#8221; instead of identity values for<strong> equals() </strong>and <strong>hashCode(). </strong>The problem with this is that many entities simply don&#8217;t have a natural key &#8211; that is, a set of one or more attributes whose values uniquely identify the entity.  And those that do often fail the hashCode() qualification that the value should not change over time.</p>
<p>There are other possible solutions I&#8217;ve seen or come up with myself, but all had at least one glaring weakness.  It seemed that there was no silver bullet for dealing with database-generated identity values in Hibernate.</p>
<p>And therein lies the silver bullet.  Don&#8217;t use the database (or Hibernate) to generate identity values.</p>
<p>I stumbled across a wonderful article on O&#8217;Reilly&#8217;s OnJava site that quite clearly describes this problem (in more detail than I do here), and offers what I believe to be the only real solution.  Check it out at <a title="http://www.onjava.com/pub/a/onjava/2006/09/13/dont-let-hibernate-steal-your-identity.html" href="http://www.onjava.com/pub/a/onjava/2006/09/13/dont-let-hibernate-steal-your-identity.html" target="_blank">http://www.onjava.com/pub/a/onjava/2006/09/13/dont-let-hibernate-steal-your-identity.html</a>.</p>
<p>And now, as I look out the window at the late February snowstorm, I think maybe it&#8217;s time for <strong>me</strong> to hibernate&#8230;</p>
]]></description>
		<link>http://blog.jeffshurts.com/2009/02/of-entities-and-identities/</link>
			</item>
</channel>
</rss>

