Hibernate for CF (and a new TransactionAdvice)

Since I added Hibernate support to CF Groovy, I've been using that for pretty much all new development.  Oh, how nice it is.  The perm-gen issue is still lingering, but if after a few projects, I've realized that you don't actually end up touching your persistent entities that much, so it's not as big a deal as it seemed it would be.  Most of the work on those is done up front, laying out properties, relationships, and various helper methods and psuedo-properties.

Yes, my apps suffer from what Fowler has dubbed an "anemic business model", but I don't have great issue with that.  It's a concious design decision, not an anti-pattern that has cropped up without my knowing.  It's specifically driven by the non-CFML nature of the persistent entities, and as such they're not really full-fledged business objects.  Instead, they're more just value objects (or data transfer objects) both inside the app and between the app and the database.  I'm also a big fan of simple, and while I'm definitely not following the all powerful "best practices", I tend to weight simple as a higher priority than a lot of people.

I've also seen a signficant shift of Groovy code from the service layer up to the web layer, which is something I wasn't expecting.  My initial thoughts were that the web layer would stay almost entirely CFML, and the Groovy would be used for the backend code and interfacing with Hibernate.  The views are still all CFML, but my controllers are growing Groovy snippets all over the place, while the service layer is mostly just interfacing with CFML APIs from the Hibernate plugin, actually using Groovy for very little.

One little piece that I have't posted yet is a "port" of my TransactionAdvice CFC for use with the Hibernate functionality of CF Groovy.  The logic is exactly the same as the original, just no ability to set an isolation, and it requires a reference to the Hibernate plugin instance.  Download here: HibernateTransactionAdvice_b4173.zip.

Cadence Retracts Offer

Cadence has retracted it's offer to buy Mentor Graphics.  Good news for the company, and hopefully good news for me too.  The chaos should definitely decrease now that the "threat" has passed, but it'll take some time to get back to normal, I suspect.

The State of the Barney

Time for another "State of the Barney" post. They're usually a January staple, but oh well.

The past few weeks (since the end of June, really) have carried significant unwanted stress because of the takeover bid for Mentor Graphics by our largest competitor. The odds of the deal actually going through are pretty slim, I think, but the whole corporation is a little jumpy. I'm also definitely in the "redundant" class of employees, so I'd very likely be gone after a token severance package, if that.

Because of the potential purchase, work has been a series of short-term "make the team seem really valuable" kind of projects. The projects themselves aren't really that bad, they're just focused on the wrong results. Frustrating for me, though, as a developer that just wants to build some cool, interesting, and useful apps.

Life at home has shared the tumultuous nature of the office since Heather's return from England on 4th of July weekend.  That's not really a topic for a blog post, however, beyond saying my lack of energy is not due to poor eating and sleeping habits.

Emery just turned three on Tuesday, and Lindsay will be five this winter.  They both head off to preschool in a couple weeks, Emery for the first time.  He's still got some Mommy issues that Lindsay never really had, so we'll see how it goes.  He really wants to go though, so any problems will almost certainly be short-lived.  The toll of the past month and a half has been

My physical activity has also taken a severe downturn.  I haven't done anything active aside from walk up and down the few flights of stairs at my office a handful of times per day. I want to get on my bike again, but it's hard to find time.  I haven't even been riding my motorcycle much of late.  I'm still far from overweight, but I'm definitely carrying more fat now than I ever have before, and it's not attributable to me getting older.

On the up side, I finally got an iPhone and it's largely lived up to expectations. Typing isn't so hot (expected) and performance leaves something to be desired (also expected – it's a Mac), but having instant access to the 'net is very nice. I've made a couple minor tweaks to some of my personal web apps, but nothing major. Biggest gripe on that front is the handling of HTTP Basic Auth, specifically the incredibly short expiration time applied to cached credentials.

Pic of the Day is a few weeks short of it's fourth anniversary and still going strong. Subscribers are continuing to come in organically, despite no marketing beyond a small text link on my sidebar to get it into Google.  That has been a very fun project to watch grow over the years – if only I could list it on my résumé.  I think I'm going to do a public "launch" at some point, but we'll see.  It's an incredibly fascinating project, though the nature of the managed assets carries an unsavory stigma to many.  Most of the interesting stuff I've done over the past few years has been centered around this app, though, not stuff I get paid to work on.

Hopefully life will improve, at least in some ways, but for now the shining points are sparse.  C'est la vie.

iPhone Coding

Yesterday I did my first bit of "real" coding on my iPhone. It actually worked pretty well, I thought, though having to switch keyboards for punctuation is definitely a drag.

I've been using MobileTerminal as my terminal client and it's pretty slick. Not a replacement for a real computer, but definitely sufficient for a quick little code tweak here and there, or some database tuning.

iPhone and Wi-Fi

The wi-fi on the iPhone is totally kick ass. I was really impressed. At home I had to manually type in my long hex WEP key, but at work (where it's a pain) the phone detected an "enterprise wi-fi" network, prompted me for my Active Directory credentials and that was it. Note that this is a iPhone getting in to a Windows environment.

With my laptop (which is a Windows) machine, I've completely failed to get on the wi-fi, instead resorting to an Ethernet cable to a spare jack. Seems silly. So props to Apple for getting this dead on.

On the typing front, I've decided that the one finger approach is way faster than trying to use my thumbs. The phone just moves around too much when I use my thumbs, so I miss a lot. I can't hit the keys quite as fast with one finger, but it's WAY more accurate.

From My iPhone

I finally got my iPhone 3G today, and am trying out the WordPress app. Typing kind of sucks, but I'll live. I've also attached a photo of my desk at the office, just to see how that works.

photo

Weka Mining Update: It Works!

Back in April, I posted about how I was using Weka to do some asset prioritization.  The gist of it was that users would rank assets on a 1-5 scale, and then then the system would recommend other assets that it thought they'd like.  This is the Netflix problem, if you're familiar with that, though without the time component.

Over the intervening months, I've gone back and tuned the mechanism slightly.  The algorithm hasn't undergone any fundamental changes, just made a few little tweaks here and there.  A cluster of related assets doesn't tell you which one a given person wants, but if you can figure out which cluster they like the best, other assets from that cluster are probably desirable.  The specifics of ranking the clusters and selecting a best fit is where most of those tweaks were made, not to the Weka implementation itself.

Here's a chart that show average rank and total ranks broken down by month:

As you can see, before the Weka switchover, the average rank for assets was  hovering right around 3.2.  That trend actually goes back a couple more years, I'm just not showing it here.  Once I started using Weka, that has gone up significantly, and is now around 3.7.  That's a pretty significant increase, especially when you consider that some asset selection remains totally random to help seed the asset pool.

MX Unit is Slick

After seeing that MX Unit on Railo had some issues, I switched over to ColdFusion and I'm impressed.  Marc, Bill, et al have done a really great job.  They've resolved a number of issues that I had with CFCUnit, and really embraced the "Integrated" in "Integrated Development Environment."

I know I'm late to the party, but it's good stuff.  When I was doing a lot of Java, having JUnit right there as a fast view in Eclipse was great.  Having to go launch a browser, find the runner app, type in the test case I wanted, and then hit submit with CFCUnit just seemed to stupid.  And if you don't want (or maybe don't have) the plugin for a specific test, running it from the browser is a snap.  Just hit the 'runTestRemote' method of the CFC and you're done.  No external runner app required.

One thing that I found confusing was webroot, component path, and facade location settings.  It seems focused on one Eclipse install per CF instance, while I pretty much run one project per CF (or Railo) instance.  And having to specify the remote facade explicitly seems unnecessary.  You should be able to give it at the root URL of the application, and it'll figure out the default one from there.  Obviously specifying a full path would be desired, but for the default, having to figure out what to type seems unnecessary.  Once I figured it all out, it wasn't a big deal, but it seemed like more work than it ought to be.

Finally, the UI is kickass.  Not that a web-based test runner really needs a nice interface, but it's appreciated.  And having the ability to switch between the rich Ext-based UI and the simple HTML one (along with the XML formats) is appreciated.

No MXUnit For Railo

I just pulled down the 1.0 release of MX Unit, and was most disappointed to see that it only works on ColdFusion:

...blah...
no definition for the class ... [coldfusion.cfc.CFCProxy] could be found
...blah...

Since I do most of my CFML development on Railo now, it kind of leaves me stuck.  Fortunately, CFCUnit works flawlessly, but with it's definitely the less compelling choice of the two.

ColdFusion Struct Literals Fail Again

ColdFusion introduced CFML struct and array literals in CF 8.  They sucked.  Assignment only, no nesting, and the use of '=' for key-name pairs instead of ':', like every other language including other parts of CFML.  CF 8.0.1 fixed the nesting issue, but not the others.  I've been trying to figure out why it's an assignment-only construct since CF 8 was released, and today I figured it out.  It's stupid.  Take this code (which fails on CF8):

<cfset s = "cat,dog,bird" />
<cfset s = {
  first = listFirst(s),
  rest = listRest(s)
}/>

If you were to convert that to the old non-struct-literal syntax, it'd probably look like this:

<cfset s = "cat,dog,bird" />
<cfset temp = structNew() />
<cfset temp.first = listFirst(s) />
<cfset temp.rest = listRest(s) />
<cfset s = temp />

That's what Railo does (or the equivalent), but ColdFusion evaluates it like this:

<cfset s = "cat,dog,bird" />
<cfset s = structNew() />
<cfset s.first = listFirst(s) />
<cfset s.rest = listRest(s) />

This will obviously fail, because ColdFusion is reassigning the 's' variable too early in the process.  In most cases it doesn't matter, but not all cases.  Worse, it doesn't give you a useful error.  Instead, it says "Complex object types cannot be converted to simple values", which while accurate, is totally perplexing if you consider the original snippet.

Note that this is a ColdFusion problem, not a CFML one.  Railo compiles it correctly (and it doesn't share the assignment-only requirement either).  OBD doesn't support literals at the moment.

Edit 2009/04/07: revised some text slightly.