Archive for the ‘Uncategorized’ Category

Pizza shop 2: Totaling the JPA Order, use P6Spy to prevent stupidity

Tuesday, March 4th, 2008

I’m digging up the original Pizza Shop project to illustrate another Hibernate gotcha (it’s probably applicable to other ORM libraries as well… admittedly, I haven’t tested it). If you didn’t read the original Pizza Shop post, you can find it here. To review, here is an ERD for the system:
Today I’d like to show how not to total up the cost of the customer order. First, we are going to add P6Spy to the project. P6Spy is an excellent “JDBC wrapper” tool that sits between your application code and your actual JDBC driver. It intercepts your application’s JDBC requests and logs the results. It’s an invaluable tool for optimizing the voodoo out of an ORM tool, and the great thing is that it’s simple to setup:

1.) Change your application’s JDBC driver from whatever it currently is (e.g., org.postgresql.Driver), to the P6Spy JDBC driver, com.p6spy.engine.spy.P6SpyDriver.
2.) Modify the spy.properties file by editing the line that starts with “realdriver=”, changing the value to your actual JDBC driver.
3.) Put spy.properties on your classpath.

That’s it! Now that we have that out of the way, let’s see just how badly we can screw up a simple method in our Model class. The method we are going to add will total up the price of an order. If you look at the ERD above, you can infer that the total cost of an order is the sum of the base price for each pizza, depending on its size, plus the price of each pizza’s individual toppings.

So for our example order, let’s say we have the following:
1 Small Pizza with Pepperoni and Mushroom
1 Medium Pizza with Sausage and Onions
1 Large Pizza with Extra Cheese

You’ll recall that we created a Model class which provides a method for retrieving a List of Pizza objects that are associated with an order ID. The temptation is to create a method which looks something like this:

public BigDecimal getOrderPriceWrong(Integer orderId) {
  BigDecimal result = new BigDecimal(0.0);
  Order order = this.getOrder(orderId);
  for (Pizza pizza : order.getPizzas()) {
    result.add(pizza.getSize().getBasePrice());
    for (Topping topping : pizza.getToppings()) {
      result.add(topping.getPrice());
    }
  }
  return result;
}

Because Hibernate does lazy-fetching, it’s not going to attempt to calculate the total cost with as few queries as possible. Instead, Hibernate’s general philosophy is to defer any queries until it knows that it absolutely needs to do them, substituting empty proxy objects for populated ones until required. Usually this is an optimization, but in this case, Hibernate will do the following queries:

1.) Query to obtain an order object.
2.) One Query for each Pizza, joined to the Size, to obtain the base price.
3.) One Query per Topping, to obtain the topping price.

In all, we get nine individual SQL queries to compute the total price of our single fictional order. The proof is in the P6Spy’s output, spy.log, truncated below:

select order0_.pizza_order_id as pizza1_2_, order0_.version ...
select pizzas0_.pizza_order_id as pizza4_2_, pizzas0_.pizza_id ...
select pizzas0_.pizza_order_id as pizza4_2_, pizzas0_.pizza_id ...
select pizzas0_.pizza_order_id as pizza4_2_, pizzas0_.pizza_id ...
select toppings0_.pizza_id as pizza1_1_, toppings0_.topping_id ...
select toppings0_.pizza_id as pizza1_1_, toppings0_.topping_id ...
select toppings0_.pizza_id as pizza1_1_, toppings0_.topping_id ...
select toppings0_.pizza_id as pizza1_1_, toppings0_.topping_id ...
select toppings0_.pizza_id as pizza1_1_, toppings0_.topping_id ...

If your application is totaling up the price of Pizza orders all day, this can really add up! An alternative approach is to use two named queries to compute the total base price, and total topping price, for an order. For example, we might add the following annotation to the Pizza class:

@NamedQueries(
{
@NamedQuery(
 name="basePrice",
 query="select SUM(p.size.basePrice) " +
       "  from Pizza p " +
       " where p.order.id = :orderId"),
@NamedQuery(
 name="toppingPrice",
 query="select SUM(topping.price) " + 
       "  from Pizza p join p.toppings as topping " +
       " where p.order.id = :orderId")
})

Then, you could add the following methods to the OrderDao:

public BigDecimal nullGuard(Query query) {
  BigDecimal result = (BigDecimal)query.getSingleResult();
  return (result == null ? new BigDecimal(0) : result);
}
 
public BigDecimal getOrderPrice(Integer orderId) {
  Query query1 = getEntityManager().createNamedQuery("basePrice");
  query1.setParameter("orderId",orderId);
  Query query2 = getEntityManager().createNamedQuery("toppingPrice");
  query2.setParameter("orderId", orderId);
  return nullGuard(query1).add(nullGuard(query2));
}

…and call into the DAO from the Model class, thusly:

public BigDecimal getOrderPriceRight(Integer orderId) {
  return this.orderDao.getOrderPrice(orderId);
}

When we run the P6Spy test now, we see a meager two queries where we used to have nine:

select SUM(size1_.pizza_size_base_price) as col_0_0_ from PIZZA ...
select SUM(topping2_.topping_price) as col_0_0_ from PIZZA ...

It pays to periodically use a tool like P6Spy on your application, to look for easy wins like this one!

I’ve included a complete working eclipse project that demonstrates this… it’s actually a tweaked version of the earlier Pizza Shop project. You can get it here.

Now hosting on blogspot

Tuesday, February 26th, 2008

I’ve moved the host for this blog from my own webhosting account, to blogspot. It should be a pretty seamless change, but I’m keeping my fingers crossed.

"Rebranding" my site and blog

Friday, January 18th, 2008

I’ve always hated “dragonflymarsh.com,” almost since the day I got it. It was originally supposed to be a cute name for my house (read the linked post if you’re really interested). Anyway, since I’ve moved, the URL really isn’t relevant to my life, and I’ve always thought it was kinda cheesy.

I’ve been unable to purchase mikedesjardins.com, because this guy owns it and now just forwards it to his LinkedIn profile (dude, that is lame!). I also can’t buy michaeldesjardins.com, because this guy uses it to post his resume. As far as I can tell, it hasn’t been modified in about seven years (dude, that is also lame!). Fortunately, I was able to purchase the humble mikedesjardins.us. So, welcome to the new place, the brand called me.

I’ve always thought it was kinda vain to use your name in a URL, but I haven’t been able to come up with anything creative that I won’t be embarrassed about in a few years. I also don’t know that I’ll have this blog forever, and need something flexible should I need a URL for personal use for who-knows-what purpose in the future. And I really don’t blog about any one topic consistently enough to name it after my subject matter. I’m stuck with my name forever, so it seems like a logical choice.

The annoying part is that I’ve spent a few years building up my “brand” of dragonflymarsh. Even with the limited success I’ve had, I’ve managed to boost my Google page rank a bit and generate some (very modest) traffic. Now I’m starting all over again. According to Google’s webmaster tools, I get (scores?) of hits on dragonflymarsh.com, and almost zero at mikedesjardins.us.

Oh well. Enough unfocused rambling. I’ll probably be redecorating this place (again) in the coming weeks. We’ll see what happens.

Tech Projects that I wish I had time for

Thursday, July 26th, 2007
  • Re-doing my personal website. Again.
  • Finding a better way to present my personal photos on my website.
  • Figuring out what I’m doing with this blog – need a vision for this, not just mindless blather to myself.
  • Creating a website for Indie Web Design work.
  • Indie Web Design work.
  • Prototyping an online e-mail system with a spam-filter idea that I have.
  • Creating a new Hibernate-Pluggable second-level Cache that takes advantage of ghost caching and other exotic caching algorithms.
  • Creating a hot-switchable cache statistic generator that sits between Hibernate and your actual second-level cache.
  • A business plan for a wireless postpaid billing provider.
  • Creating a clock and/or weather applet for Avant Window Navigator on Linux. Mail notification that works w/ Evolution and/or Exchange would be nice, too.
  • Documenting some Stripes examples for my blog.
  • Creating a Stripes “component” for a generic paginating grid.
  • Learning more JavaScript.
  • Establishing a corporate entity for potential future contracting work.
  • Creating a Firefox plugin that continuously reloads a page until it’s available for use with web development.
  • Developing a better Subversion standalone GUI client, perhaps in Java.
  • Developing a better standalone log reading GUI (like Apache Chainsaw, but better).

Bring Back the Applet!

Wednesday, July 18th, 2007

In my current job, I’ve taken the plunge into Java Web UI development. Before this, I did middle-tier web servicy stuff, so this is somewhat new for me. We are using the Stripes framework. The only other framework I’ve had any exposure to is Jakarta Struts, and I’ve gotta say that I like working with Stripes a whole lot more. But that’s a topic for another post…

Anyway, now that I’ve actually gotten some front-end UI stuff under my belt, it strikes me just how terrible of a medium the web is for creating applications. What on earth are we all thinking? It seems like each web framework, and indeed the whole servlet/application server paradigm, are one giant hack to work around the fact that the web’s client/server topology is ill-equipped to handle the type of interaction that the users are demanding.

For example:

  • How many lines of code have been dedicated to maintaining session state?
  • How much work and effort continues to be invested in technologies like AJAX and DHTML to make web pages feel more dynamic? For that matter, how many web sites resort to using something like Flash to achieve these effects?
  • How many lines of Javascript exist for the sole purpose of cross-browser incompatibility?
  • How much work does it take to create and maintain a framework like Stripes (or Tapestry, or Webwork, or whatever)? These frameworks seem to exist as an attempt to provide and abstraction, allowing developers to work in a more familiar, intuitive, “event-driven” environment than the submission-driven web environment.
  • All of these frameworks promise to separate the “HTML designer” from the “programmer” (especially frameworks like Tapestry). The theory is that more aesthetically-minded designers can focus on their jobs, while the grunt-work developers can concentrate on the mundane business logic. But does that ever really happen in practice? Perhaps it does, but I’ve never seen it (maybe it’s just the nature of the kind of work with which I’ve been involved). Making an application that actually does anything of consequence almost always causes leakage between the presentation and business layers.

I’ve understood that these things were problems for a while now, but I never really understood the magnitude of it until I got my hands dirty, and actually began developing a real web-based application for work. I feel like I have an understanding of how it all went wrong. Browsers became the ubiquitous presentation client-of-choice in the 90′s. The internet’s popularity exploded, IE was installed on everyone’s desktop, and people pushed the technology to its limits as the user-base broadened and user’s needs were identified.

I remember when Applets came on the scene in the mid-90′s. I was one of the early adopters… I downloaded Sun’s pre-alpha “HotJava” browser, and later the beta version of Java with Netscape 2.0. Back then, applets suffered from a lot of drawbacks:

  1. You had to download the Java plugin separately.
  2. Programs started up SLOWLY as they were downloaded over your 14.4kbps dial-up connection and the JVM was launched.
  3. The AWT was a bear to work with, and the output was pretty darned ugly

Applets ended up being used for stupid stuff like animated stock tickers. Eventually Microsoft made its own incompatible JVM, then stopped shipping it altogether, and the rest is history.

It’s really too bad. A lot of the items above have been addressed. Java WebStart can push a JVM to the user so that the download of the JVM is simple (admittedly, this applies more to applications than applets – but I still don’t think that this is a reasonable barrier. People download flash plugins all the time!). Broadband is very prevalent today. UI development has come a long way since the AWT in 1995.

Swing applications already follow a natural, intuitive, event-driven UI model. The controls are object oriented and have a familiar appearance. The applications are stateful. The JVM behaves the same way in any browser.

It’s a shame that we can’t reduce the browser as a delivery mechanism for applets, instead of insisting on shoehorning interactive AJAX/DHTML/Flash applications into web pages that seem better suited to serving their original purpose – static content.

First Week on the New Job

Saturday, June 16th, 2007

I started a new job this week. After over seven years with my last job (with two different companies), I’ve made the leap. It was quite difficult for me – I feel like I invested a lot of myself into the product that we were producing at my last gig. Perhaps that’s a bad thing. Learning to separate myself from the product that I generate has always been difficult for me.

One might think that it’s a good thing to be emotionally connected to what you create at work. That’s how the good artists and craftsmen feel, isn’t it? But programmers aren’t really artists. Appreciating and analyzing code requires a certain level of objectivity, free from personal biases. This is particularly true when others are reviewing your own code.

On the other hand, many of the best programmers I’ve known seem to think of themselves more as artisans or craftsmen than scientists or technicians. An elegant algorithm or piece of code has a certain je ne se quois that an experienced developer will instantly recognize. Is it art?

Anyway – I’ve gotten a little off track. I’ve switched jobs. And I’m now immersing myself in something that other people have created and (from what I can tell) are pretty attached to. It’s hard not to feel like I’m a bit of an outsider. I’m sure that will go away with time. The other artists have to objectively evaluate my work first. :)

Reverse-scaling a company

Thursday, May 17th, 2007

The company that I work for recently underwent a pretty deep round of layoffs (our newly acquired India office was, not surprisingly, unaffected). The thing is, even though we reduced our workforce by about 20%, the management structure is more-or-less intact.

My company has fairly rigid boundaries between each group. Group A has a very specific job that entails nothing that Group B does. The responsibilities are usually very clear-cut, and heaven help the poor soul that unknowingly crosses a boundary into another group’s zone of responsibility.

So anyway, during our first layoff (the one prior to this one), we were promised by our then-COO that we’d work to become more agile, more nimble. It was going to be important now that we were smaller… we’d need to wear more hats and think smarter yadda yadda yadda.

I’ve decided now that if you ever hear an executive say things like that, it means that they really have no plan.

The problem is that no one is willing to look at the hierarchy that was created in better times, and reduce the layers. In a small company, you don’t have the team-that-works-on-that-side-of-the-building who has so-and-so as their leader that performs role X, and the team-that-works-on-the-other-side-of-the-building who has such-and-such as their leader and performs role Y. In a large company, people are divided into discrete rank and file that execute their particular team’s tasks in the context of a larger company goal. That structure evolves over time; as it becomes evident that specialization is needed in specific areas of a company’s business, a group is formed and a leader is chosen. It seems like lots of careful thought and practice has gone into how to scale the company as it grows larger, but no one prepares for the prospect of shrinking, and no one is quite sure how to do it.

I can think of reasons why this is the case. Firstly, I’ve always thought there was sort of a natural equilibrium point for direct-report-to-manager ratio, and that ratio depends on how much time the manager spends doing stuff that the direct reports also do. For example, in my line of work (programming), I’m a manager, but I still spend a lot of time programming. That means my team has to say small, because otherwise, I wouldn’t have enough time to adequately manage them (some might argue that I don’t adequately manage them now, and they’d probably have a good case against me). I think that point is somewhere around a team size of four people. You can probably get away with up to 6 or 7 if the manager isn’t doing any of the same stuff as the direct reports. And my whole theory probably falls apart if you get up into executive levels, but I’m basing all of this on personal experience and I haven’t had the honor of serving in an executive capacity.

Anyway, when the company gets “healthy,” it seems that the managers get to concentrate solely on managing, which leads to bigger teams with managers that have been out of the day-to-day work for a while.

But what happens when the teams go from rather large, to rather small?

During the layoff, it seems like you have two choices:
- Let go of the people in middle management who have lost most of their technical skills. These people usually have the most seniority, and are the most connected to the people decided who stays and who goes. So it’s more likely that you won’t go this route.
- Let go of the people with the least seniority, fewest “connections,” etc. Methinks corporations often prefer this one.

The problem is that managers haven’t done any technical work in a long time, and aren’t really as capable of pitching in and helping with the daily grind. But they’re still around. And the old structure stays in place even though you’re supposed to be “leaner” and more “nimble.”

I don’t know how to work out of this conundrum. I’m curious to find out how my company will pull it off. I’m not claiming that the company should have laid off all of the middle managers… hell, I *am* one of those! But it’s very hard to take an organization that has built itself up over time and de-construct it, reversing time and returning it to the smaller group it once was. I don’t even know if it’s possible.

RESTful services on FTP?

Tuesday, April 24th, 2007

I’ve been reading and thinking a lot about REST lately. There’s a good high-level intro to REST here, here, and (of course) here. I suppose part of my interest in it stems from my recent projects at work. I was part of a team that exposed a bunch of our product’s functionality as a brand-new SOAP API. What struck me was how complicated it all is. It’s supposed to be a simple way to use standardized formats to enable an RPCs across and among disparate technologies, and for the most part, it delivers (Idiosyncrasies like getting a .Net SOAP client to pass dates to a Java SOAP servers, and vice versa, in different timezones, with null dates, notwithstanding). But the steps involved in creating the service, exposing it, generating the WSDL, embedding that WSDL in the deployed war file, then getting the clients to generate stubs from those WSDLs and making it all work… well, it’s cumbersome. More cumbersome than it oughtta be. Full disclosure – my only exposure to creating SOAP web services is through Apache Axis. I’ve heard that CodeHaus’s XFire and even .Net are easier to work with.

So reading about RESTful services was like a breath of fresh air. Now, every article I’ve ever read says that REST does not necessarily need to use HTTP as its transport protocol, but then they invariably proceed to discuss how HTTP’s GET, POST, PUT, and DELETE commands map really nicely to the ubiquitous CRUD database operations, and explain how to implement REST on HTTP. But I wonder if it wouldn’t make just as much sense to implement a RESTful service on FTP. Why not? The “resources” in both cases are basically file pointers. You could do get, put, and delete, and navigate through the hierarchy of resources with cwd. For transferring large files, the FTP protocol might actually be better suited for the task. So, e.g., let’s say you have a DSS application where you’re transferring large batches of data to a data warehouse from an OLTP database. Why wouldn’t this be a perfect situation for creating a RESTful service over FTP?

Latest news on the Mac

Tuesday, April 24th, 2007

So, I guess I have two things to report…

1.) I have an old Windows 2000 machine in our office. I use it basically as a glorified terminal emulator to work. It has a VPN client and a Remote Desktop client, and that’s about all it’s capable of running. I do like to have a printer hooked up to it, though. Well, the airport extreme didn’t “just work” with it out of the box. The airport extreme is different than other wireless routers I’ve had. There’s no goofy web interface to configure it, and there’s little visibility into what it’s actually doing. You need to use Apple’s client to do much of anything with it. So you can imagine my disappointment when I inserted the airport extreme CD into my old Windows 2000 box, and got a sad little dialog window stating that I needed to have Windows XP for it to work. Fortunately, I found this website that walked me through how to set it up manually. After following the steps on that page, things worked great.

2.) I find myself holding down the Control Key and clicking, instead of right-clicking, when I’m at work on my windows machine.

From my recent blog rants, you might thing that I don’t like the MacBook. In fact, it’s not true at all. I love the machine. The interface and the hardware is gorgeous, and the software that is on it works perfectly. OS X totally rocks. But it seems like Macs are burdened with the same interoperability problems that Windows machines have. If anything, it’s a little bit worse for the Macs. I guess I’m a little disappointed by that, but I probably shouldn’t have been naive enough to think that all of those problems would disappear when I upgraded.

It "Just Works" my A%#!

Wednesday, April 18th, 2007

High winds in southern Maine caused massive power outages, which kept me from playing with my new Mac for a couple of days. I decided I needed to print stuff, so that would be the next task.

So I have this crappy old Belkin “Wireless” print server – I put that in quotes, because the thing has never functioned wirelessly. I eventually ended up giving up entirely and relying on the thing’s ethernet port. I had planned on limping along with the old thing with the new laptop. Imagine my surprise when I discovered that my old driver CD did not have any Mac support. And it’s not some standard, simple thing that a generic driver would work for. This piece of art actually somehow pretends to be a USB port on the local machine, and the traffic is intercepted and somehow routed to the print server to get to the printer. I.e., it’s a hack that will never work for my Mac.

So I figured, what the hell, I’ve already spent way too much on this laptop anyway, I might as well go whole-hog and buy Airport Extreme! Which is what I did.

But the HP-supplied drivers for my Photosmart 7350 could not find the printer. I went to the printer tool, and the printer was not showing up on “bonjour” (Apple’s cutesy name for wireless device discovery, I guess) like it was supposed to.

I don’t know what happened, I rebooted the Airport Extreme thingy a couple of times, and somehow managed to get it to work with an alternate driver (there was no driver for Photosmart 7350 on the list in the printer setup utility).

Ironically, I actually got it to work with windows easier! The Windows-based bonjour utility actually found the printer and set it up on the first try.

I still like my Mac and all, but I think the “just works” mantra is probably a myth.

As an aside, there is no company that devotes as much attention to packaging as Apple. They could teach seminars on packaging based entirely on Apple. The airport’s white box with its solitary, stark LED is sexy, but so is the box that it came in. This always seems to be true with Apple stuff. The shiny, perfectly creased cellophane that wraps the items is always just a bit more crisp than ordinary cellophane. The cardboard is placed perfectly for the box contents, with simple text “Designed by Apple in California” inside. I once bought replacement ear pucks for my iPod and was amazed at the detail in the packaging.

I’m sure it’s intentional, but as far as creating an experience that exudes “high end” computing is concerned, Apple’s packaging “just works.”


© 2012 Mike Desjardins. All Rights Reserved.