Wednesday, February 3, 2010

Hibernate/JPA confuses "legacy" with "high throughput", "scalable", and "complex"

I like Hibernate/JPA for dead-simple inserts and update. I detest it for queries. I also detest how the Hibernate documentation totally misuses the term "legacy". When I hear the term "legacy", I think "old and dumb". But on planet Hibernate, "legacy" means "Any application which operates on a piddly amount of data and doesn't buy into our myopic, java-centric view of the cosmos in which a relational database is just a pain-in-the-ass file system whose performance and data integrity issues exist only to perpetuate the hiring of very expensive DBAs".

For example, Hibernate says it doesn't support trigger-driven sequence creation because that's a "legacy" kind of a thing. What if my database is accessed both by Scala, Ruby, Perl, and Java? I'd like to encode some core business rules directly in the database so I don't have to duplicate logic in different languages. I don't call that "legacy". I call it "reality".

Hibernate thinks that compound unique keys are indicative of a "legacy" database. There are perfectly good reasons--from a (gasp!) data modeling perspective--to use complex unique keys and dispense with primary keys. Having to introduce new artificial primary keys into all my tables to make life easier for the object layer is something I am now more or less required to do so as not to infuriate application developers. But there is a real cost to the data model: the data model is forced to violate DRY. The data model has to maintain two redundant definitions of uniqueness: one that is natural and one that is imposed by Hibernate. Hibernate claims that having a foreign key refer to a unique key of the associated table rather than the primary key is "complicated and confusing". This is bullshit.

Hibernate thinks that only "legacy" tables have lots of columns. In reality, it's often very useful to make really fat tables to accomodate what would otherwise be complex, possibly inefficient multi-table queries. I've made fat tables before and I'll make them again. It's not legacy, it's reality.

Hibernate thinks that everyone should have "fewer tables than classes", and then claims that storing some attributes in a secondary table (hello @Secondary annotation) is really only for...you guessed it..."legacy" databases. Hold the phone. What if I have some bit of data that is part of an object but needs database-level security? For example, if I have a patient table and I want to expose access to social security numbers, perhaps I'd like to put the social security numbers in a separate table, or in a separate schema, and have the database manage the security of this table slightly differently? What if I have some huge freakin' columns that map to a particular subclass of an object, but I'd like to keep them stored separately for query performance? What if these columns are extremely rarely used? I don't want to risk pulling them all into memory (which I can control by FetchType.EAGER). I want to manage the storage for these data differently. Maybe the data is so large that I need to partition the backing tables. Hibernate seems to be saying that these situations are for those stupid old "legacy" applications. Just let your object model define the data model! What could possibly go wrong?

My needs aren't legacy needs. These are the needs of reality.

Tuesday, January 26, 2010

Installing artifact: [your file name here] (Input/output error), Result too large, and disk errors.

From time to time I was getting the "[INFO] Error installing artifact: [your file name here] (Input/output error)" error message from Maven. It started happening at seemingly random points during maven builds but it seemed to favor bonking on large zip/war files. Then I started seeing "Result too large" errors. At that point I made sure I had a clean backup on the sever, rebooted, and crossed my fingers.

My machine failed to boot. It just sat there with the black and white whirly thingy Mac startup screen.

I chalked the problem up to I/O gremlins from the planet Zorng, so I called my IT group, who dropped the Disk Utility and Disk Warrior bombs on my SSD. After they were done, I had to manually refresh my Spotlight index, which took a few hours, but then things were back to normal. One other thing I learned: don't let IDEA attempt to re-index files until *AFTER* you've let Spotlight update its own index.

Saturday, January 23, 2010

Ice dam prevention time!

The neighbors must think I'm a bit nuts for how often I rake snow off the roof. At least that's what I thought until I saw the guy across the street actually climb up on his roof in January with a shovel and start shoveling it off. I use a very long roof rake to clear snow and I stand on the ground. Getting up on an icy roof in January in New England strikes me as suicidal, but anyhoo...

When the weather is super cold, there's really no point in clearing the snow off the roof because it forms a nice, solid icy barrier. This is actually a handy type of insulation...but when things start to thaw, that's when the ice dam beast can appear. By that time, it's impossible to clear the snow off the roof because it has hardened to a solid icy mass. Even if you did chip away at it, you'd likely start hacking off roof shingles along with the roof, throwing out the baby with the bathwater as they say. So you gotta rake the snow off the roof when it's nice and fluffy. Otherwise, you're screwed come spring or that ever unpredictable February deluge of 3" of rain and 60 degrees (followed by another month of temperatures in the teens of course--welcome to New England).

So my advice is: roof rake early and often. Gently bash ice and snow out of the gutters whenever possible. You'll get no payoff (other than huge triceps) until it starts raining when you have a foot of snow on your roof. If you have a uniformly steep roof, you can probably safely ignore my advice. But if you have a very bungalow-y roof, with lots of changes in pitch and some relatively flat roofs, go get a roof rake.

We have a few feet of snow on the ground and the forecast calls for about 2" of heavy rain in the next few days. Here's when I get a bit bonkers, trying to clear yet more snow off the roof, running around outside, digging the downspouts out of the snow and trying to dig little snow trenches so that the roof water will drain away from the house.

It's great exercise. Kettlebells are a good workout for snow shoveling and roof raking. I'm hoping the effort pays off and we don't see any rain in the basement.

Friday, January 22, 2010

Aphex-Twin induced insanity

Here's a way to make yourself go crazy: write code for 8 hours straight while listening to Aphex Twin. You could keep one song on repeat or shuffle. It don't matter. I love Aphex Twin, but I'm about to walk out the office in a fugue state.

Sunday, January 3, 2010

Uncorking old emails

While putting the Christmas ornaments under the eaves, I stumbled upon some CDs of 10+ year old college email. My attic gets wicked hot in the summer and cold as ice in the winter, so I popped the CDs into my laptop just to see if they were actually readable.

Amazingly, they were. Amazingly for a CS graduate, I moronically left my email in a number of formats:

1. Some binary that might be an encrypted WordPerfect file from 1995. Or it could be the format DOS uses when you copy things spanned across multiple floppies. I can't quite tell yet, but I think I'm going to have to write some code to figure it out.
2. Pegasus Mail, circa 1996
3. Eudora from 1997
4. Outlook in 1998--good luck parsing a .pst file
5. Scattered clean text files from Pine

So what's a fella to do? Install VMWare or Parallels, find an old Windows 95 key and some more backup CDs with ancient versions of the relevant software, and hope to God that I can extract all the proprietary formats into a simple text format so I can just "more" the files while I knock back some cold ones.

I worked very hard during college, but you wouldn't know it from my email trail. It appears I just sat around whining very, very verbosely about women. Even accounting for typing about 90 wpm, the sheer volume of email I produced and read makes me think I misspent my college life writing and reading email at a time when people thought you were a complete loser if you used ntalk or ytalk. Fast forward 10 years and now you're a loser if you don't use IM in one form or another. Huh? We were definitely ahead of our time.

A weird thing happened to me while reading what should have been safely defused emails from distance of 10 years: I got pretty stressed out. I had some unhealthy relationships (physically and email-wise) with this one girl in particular and after reading a few of our exchanges, I started sweating as if the conversation was happening right now. The only thing I had to anchor me in the here-and-now 10 years later was the fact that I was reading the email in a slightly different font on a Mac and not on a DOS terminal plugged into Pine. But I was reading it in Terminal.app, which tells you something about the staying power of the command line.

So to all you young'uns out there with your fancy communication tools: extract and save everything in ASCII. And wait 20 years before re-opening the emotional mine field that is your college email.

That last bit of advice might not apply to anyone except folks in college between, say, 1992 and 2001. First discovering email during college is sort of like first discovering your genitals at the age of 19. All of a sudden there's this incredible tool at your disposal, you have no idea what the rules surrounding it are, it's the source of pleasure, fun, regret, fun, pleasure, shame, regret, pleasure, and by the way, you're drunk and high often while you figure out how to use it, and no one else knows or has any experience with it, so you all stumble around equally ignorant, diddling anything that moves. Eventually people start catching the clap and figuring out what the boundaries of email are.

Hence the outrageous amount of oversharing in both my inbound and outbound college emails. Back in the mid nineties, there wasn't a trivial way to share things online. Heck, some email programs didn't even have a GUI, much less a "forward" feature or BCC. The boundaries around email were very similar to those around mail: mail was private, so email should be private. Because of this assumption, people tended to be much more revealing on email, at least in my experience. There's a lot of self-incriminating stuff in my college email. I doubt college kids these days make the same blunders because the assumption these days is that anything in a computer is inherently unsafe, and if you email a picture of your hoo-ha to someone, that shit is going to be all over the interwebs in no time.

Kids these days learn the same lessons I learned about email, IM, and texting/sexting, but instead of learning them while getting stoned at the age of 20, they figured them out while drinking apple juice in preschool. I think that qualifies as "progress".

Tuesday, December 29, 2009

Thrift sounds nice, but installing it is painful

Using Thrift to solve various cross language web services problems appeals to me. Basically you define your service interface in some very simple IDL, and then Thrift generates client and server stubs in various languages. To startup a server, you fire up a main() and use some canned multithreading libraries to build a robust server. Checkout the whitepaper for further details. Those crafty authors took the time to write a whitepaper in tex, just to give it the feel of quality research.

So, you're all ready to install Thrift on a Mac. It's a nuisance, but at least it's reasonably well documented.

But what's a killer is that the Java tutorial code is utterly busted--like it won't even compile for God's sake. To get it to work, you have to:

1. Download some logging junk from slf4j.org. Then add slf4j-simple.jar and slf4j-api.jar to the classpath of the build.xml.
2. Add the same two jars to the JavaServer and JavaClient shell script classpaths.
3. Edit the generated source files. Are you kidding? Edit the freakin' generated source? And this ain't no Java6 problem--this shit won't even compile:

thrift-HEAD/thrift/tutorial/java/src/JavaServer.java:66: duplicate case label
case Operation.DIVIDE:


thrift/tutorial/java/src/JavaServer.java:77: incompatible types
found : tutorial.Operation
required: int
io.what = work.op;

The fixes are straightforward: Remove the qualifying class from the switch statements, and assign some number (I used work.num2) to io.what.

Then things seem to work.

That's one sloppy tutorial. By making such high barriers to even running the tutorial, the Thrift team has really slashed their user base. It's too bad, because I suspect Thrift is really pretty awesome.

Monday, December 14, 2009

Knucklehead Insulation Strikes Again

Shortly after we bought our house, my dad poked around in our side attics and mumbled something about how the insulation was all messed up. At the time, my main priority was on the creature comforts of my 3 month old daughter, which had nothing to do with insulation. So ignored my dad's observation for a few years, until an unrelated roof leak called me up to the side attics. Sure enough, the insulation was a mess.

The top half of the roof is actually properly insulated, with rigid foam, a thermal barrier, and about a 1.5" air gap between the foam and the roof decking. The guys who installed that section knew what they were doing.

Some clowns did a far worse thing on the bottom half of the roof: R-11 insulation jammed all the way up to the roof decking. R-11? In the attic in New England? The attic in my region is supposed to be at least R-38, ideally more like R-60. Why not just hang up a bedsheet and call that insulation? These bozos also didn't know anything about insulation's tricky pal, ventilation. By blocking the airflow at the lowest part of the roof, the job effectively blocked ventilation through the entire roof, rendering the ridge vent worthless. Thus the roof bakes in the summer, which in turn raises the temperature of the top floor, which forces me to shell out way more money for air conditioning.

We have a few knee wall doors which also exhibit a 1980's "who gives a shit?" attitude in regards to heating costs. In the winter time, our precious heat goes right out the knee wall doors, into the side attic, through the R-11 faux insulation, and right up to a pitch change in the roof deck. Nice warm air hitting the lower portion of a roof in the winter is a recipe for something I hate more than the 1980's LA Lakers: ice dams. The escaping warm air contributes to uneven roof temperatures, which, to make a long story short, are the basic cause of ice dams. So the shoddy insulation job leads to more than just inefficient heating. It wears out the roof much faster than it should (hello, $8,000 roof job) and it causes ice dams which--in case you didn't know--lead to water trickling inside your house in ways you thought were impossible.

You can bet I'll be fixing this problem soon with air chutes, rigid foam insulation, and a thermal barrier.