Monday, January 30, 2006

Primary Care Physician's Afraid of My Insurance

It never ceases to amaze me how insane this nation's medical system has become.

As you may know by reading some of my older posts, my family has been through the ringer with health insurance. Even though my wife is back to work with access to "real" insurance, my son and I continue with the NASE package serviced by MEGA Life and Health Insurance. The key ingredient of this package in my situation is that it qualifies as a high deductible plan as required by the Health Savings Account laws. As such, we can pay for small medical expenses with pre-tax money.

So back to the point...at my current Doctor's office, I keep getting calls everytime I make an appointment (which is fairly frequent, all things considered, because I'm extremely susceptible to lung infections) checking to see if I know that my insurance does not cover routine Doctor's visits. At this point, I just say "yes" and move on.

Unfortunately, the Doctor's office doesn't let it end there. When I arrived for an appointment last week, the person who checked me in at the desk asked if I had been called. I said "yes" again and said that it would be nice if the question wasn't always asked prior to an appointment. The attendant then said they could take my insurance off of my file so it wouldn't be an issue. I then politely informed her that I'm part of a group policy and that I receive a discount for Doctor's visits even though they are not covered under my plan.

At this point, we start running in circles. This happens almost everytime my son or I go to the Doctor.

The insanity here is that people are so conditioned to believe health insurance should cover everything. Even the Doctors' offices who see anything and everything in terms of insurance fail to understand a high deductible policy. Insurance is about protecting you from a catastrophic financial loss, not from a $120 trip to the Doctor to get treated for a sinus infection. How much would car insurance cost if you had a $10 copay for every oil change?

Labels:

Working with Other Software Developers

Over the years, I've employed four software developers and contracted with a couple. In all of these cases, it never ceases to amaze me how they fail to follow instructions.

Take my current situation as an example. My company has contracted with a developer with a resume that should intimidate any potential co-worker. Yet, when I give him some of the simplest instructions such as:


  • Use Spring's Annotated Transactions for DAOs

  • Move 3rd party libraries to the lib directory

  • The project must build at the command line and not just in an IDE



He routinely fails to follow them.

In the first example, not only did he not use Spring Annotated Transactions, he didn't even use Spring's wrappers for Hibernate DAOs.

In the second example, he sent me an e-mail proposing creating a lib directory in the project for the 3rd party libraries. Huh?

In the third example, it has become obvious he just doesn't want to leave the IDE.

So, my question is this. Is he:


  1. Feigning ignorance to do the project the way he wants knowing there is little time to go back and change some of these things?

  2. Stupid?

  3. Unable to grasp the level of complexity required in a mid-sized web application?



Based on my experience, I'd say (b) is the most likely culprit with (a) thrown in for a little variety. I know some would object to me calling him stupid, but consider this...if he doesn't follow the instructions of the person who writes his check, what is he????

Labels:

Friday, January 27, 2006

Highpoint RocketRAID 1820A Review

In a recent quest to add a 1+ terabyte media server to my home network, I stumbled onto the Highpoint RocketRAID 1820A. This RAID interface supports up to 8 SATA drives with support for RAID levels 0, 1, 5, 10, and JBOD at only $208.00 through NewEgg.com.

If you have ever hunted for a RAID 5 card, finding something that does true hardware RAID for a reasonable price is next to impossible. Even if you do find it, the chance of drivers being available for anything other than Windows is near 0. Nevertheless, Highpoint delivers hardware RAID 5 with drivers for Linux, FreeBSD, and even Mac OS X. It also supports Windows if you prefer.

Labels:

Tuesday, January 24, 2006

MPAA Violates Copyright

This is just too funny not to post...

MPAA admits to unauthorized movie copying

The best part is that they cite fair-use because there is no monetary gain. And why can't I rip a DVD to a computer hard drive to play on my HTPC again????

Labels: , , ,

Will I Use Hibernate Again?

Short Answer: Probably Not

Over the past 2 years, I've been reading about the wonders of Hibernate and how much simpler it makes CRUD operations. For two recent projects, I decided to take the plunge and use Hibernate. The purpose of this post is to explain some of the reasons I am not likely to consider Hibernate in the future.

Now, to be fair, I did not use raw Hibernate. I used Hibernate wrapped up by Spring, but if you're familiar with both, you probably know how much simpler and prettier Hibernate is if wrapped by Spring. So, I consider my experience with Hibernate more positive than it would have been without Spring. Feel free to tell me why I'm wrong.

Anyway, as you get into developing an application with Hibernate after having spent years on JDBC, ODBC, and the like, you achieve an initial euphoria over how simple it is to perform CRUD operations on the database. In my case, I wrote POJOs, mapping files, and SQL scripts and quickly had a simple schema up and running with full insert, update, delete, and select functionality.

Of course, Hibernate can make life even simpler by letting you create POJO's and SQL scripts from the mapping files. You can also create mapping files and SQL scripts from POJOs using annotations. Needless to say, there are a lot of tools that can make Hibernate even nicer than what I used.

So, you're probably wondering what is my problem. Good question...

First, let's talk about Lazy Loading. Over the years, I've written who knows how many lazy loading methods within a class to improve performance in situations where a given set of data might not be needed. It is a sound principle of database application development as long as it is fully documented. One aspect central to all lazy loading systems I've ever written, though, was the ability to connect to the database and get data regardless of the context.

What does Hibernate do? It throws your friendly neighborhood LazyLoadException anytime its session disappears. Due to the architecture of my system, it ended up being easier to turn off lazy loading everywhere than to have to hold Hibernate's hand everytime it needed a session.

Of course, turning off lazy loading introduced Hibernate's second major weakness...performance. If you have a database schema of any size/complexity, loading data can become quite cumbersome. Of course, Hibernate offers some ways through custom SQL to improve performance, but at the end of the day, does that buy you anything over iBatis?

Next, let's talk about error messages and exceptions. If I attempt to perform an operation on the database where I forget to provide a value for a not null column, I expect to get an error that says something about that column. What does Hibernate do? If you're only dealing with one table, it probably reports the right error. However, if you're dealing with a group of related tables, take your guess.

In one notable instance where I had a table with a one-to-one relationship to another table setup with full cascading, an error in the mapping of one table during an insert resulted in an error saying that the foreign key column couldn't be null. The real problem, however, was that the insert of the row in the related table failed due to a null column with a not null constraint. Until we learned that Hibernate exceptions were useless, we wasted a lot of time tracking down the wrong problem. The best debugging option is to look at the generated SQL.

Now, you may say, "...but what about your test cases for the related table?". Sorry, but I'm never given enough time to write test cases for every little thing in an application. You can wax poetic all you want about extreme programming concepts or whatever flavor of the month development method gets your goat, but I've programmed both ways, and writing test code takes longer unless your developers are incompetent.

Ooh...hope I didn't step on any toes there...moving on...

So let's talk about the biggest insanity in Hibernate...attached and detached objects. While some of these issues tie into lazy loading, there are still problems even if lazy loading is turned completely off.

Hibernate likes to promote itself as being easy to program because you use simple POJOs instead of complex EJB objects to move data in and out of the database. Of course, that's only a half truth. The real truth is that Hibernate introduces proxies throughout your code to create their imaginary universe where these are "just POJOs". Once the proxies get their hooks into your object, you can kiss simple POJO functionality like sending the object over an XML RPC protocol goodbye. Chances are that it will fail to initialize properly when it gets to the other side.

The only way I could overcome this little bit of fun was to completely reload any mapped collections included in an object that needed to go over the wire. Of course, turning on the delete orphan functionality of cascading relationships added some new fun to the mix. Hibernate detects the fact that you have disconnected the parent from the child and gripes about it with an exception. So, you really don't have a simple POJO that retains all of the fine qualities of a POJO after you let Hibernate dig in.

Now that delete orphan has been mentioned, it's a nice time to segway into a rant about its implementation. It appears as though delete orphan was designed to work exclusively with Hibernate's own collection implementations. When you perform an operation on the collection, the collection does whatever merriment it wants in the background to track the operation and reports back. Hibernate then takes the information stored in the collection and makes the same changes to the database.

Side Note: Going back to the issue above, why if delete orphan only takes action in the database upon a save/merge of the parent object does it need to track the fact that I'm tossing the Hibernate persistent collection in favor of a simple, java.util collection?

When I think of delete orphan, I think of the database loading the list of rows from the database, comparing it to the list of rows in memory, and executing the appropriate insert, update, and delete statements to bring the database in sync with the in-memory representation. Hibernate's idea of delete orphan seems like someone took the easy way out.

Don't get me wrong. Hibernate's method could be useful in some circumstances, but I want to be able to take a POJO, without any proxies or special collection classes, and have it persisted to the database just the way it is in memory with all of the dependent collections persisted correctly as well.

All of these issues caused me to spend considerable time digging through the Hibernate forums and Google looking for ways to circumvent these problems. In all of my searching, one thing always rang true. Hibernate developers act like a bunch of arrogant, holier-than-thou programmers labeling anyone and everyone incompetent while lauding their creation as perfect. Nice OS community building there guys. You definitely kept me from ever posting on the forums or, even worse, contributing to your project.

Of course, not all of my experiences with Hibernate were negative. Some of the good things:


  • Database Independence: One application we wrote runs Apache Derby for the Swing GUI and PostgreSQL at the web server.


  • SQL Queries: Taking advantage of object mapping by writing raw SQL queries was extremely simple.


  • Scalar Queries: Hibernate turns scalar queries (thow queries that do not return a mapped object) quickly and easily into an Object[][].



Unfortunately, the benefits do not outweigh the costs. Hibernate feels to me much like Ruby on Rails must feel to many Java developers. It's great for quick and dirty jobs, terrible for the big stuff.

Let the flaming begin...assuming anyone reads this stupid blog.

Labels:

Friday, January 20, 2006

Is it 2008 Yet?

Even though I lean slightly Right of Republican (aka Mildly Libertarian), I have to admit that I felt like George Bush was the best guy for the job in the past couple of elections. In the primaries, I liked Forbes for his tax strategy, Keyes for his honesty, and McCain for practicality. However, none of them were viable candidates when you consider the opposition. In the general election, visions of Gore's extreme liberal tendencies danced in my head, and Kerry just rubbed me the wrong way. I guess you could say Bush was the best electable alternative.

Shortly after 9/11, I began to believe that Bush was not only the best electable alternative but possibly the best guy to have in office at the time. Thinking about Gore being in the White House during 9/11 still gives me chills to this day.

It wasn't long, however, before Bush was plunging us into Iraq, shaking my confidence in his administration. It was only toward the end of the Iraq War where I recognized the genius behind it. This wasn't about nukes or terrorists or oil or even personal vendettas...this was about shifting the location of the War on Terror. Bush gave the terrorists a military target on foreign soil as a means of protecting civilians in the United States.

Now, though, we hear about Bush's domestic spying program, and just this week, Bush asked Google to turn over their search logs to defend a lawsuit related to yet another law about pornography. That's not to mention his ongoing support of things like the Patriot Act and the DMCA.

So, I'm starting to wonder...is it 2008 yet? If not, how far do we have to go?