Monday, May 30, 2011

Fun with Hibernate: Retrieving an object that should have no references

So I think I'm just going to call this a series, since there seem to be a lot of episodes of me and Hibernate not getting along.

This particular problem arose a couple weeks ago. It turned out that when you were on the website and clicked on a recording to bring up its detail page, a NullPointerException would be thrown. Great! There wasn't an obvious solution so I just logged it in our issue tracker (issue #68)

Then it looked like it only caused a problem with a specific recording (with id=4). Even more exciting was that the spot where the exception occurred was completely unrelated to the cause. Instead, it was being generated in the data layer when the query was made. Well that's never good.

Eventually we found that our Recording object, which contained a List of SongInstances, was causing the problem. One of the SongInstance objects was null. The weird part was that each SongInstance had a foreign key to a Recording. Since no-one had a reference to SongInstance, deleting a SongInstance should not have impacted anything.

Well, turns out the problem was caused by two things. First, one of our 'integration' tests tested deletion from the database (oops) and we don't have a test database yet. So it deleted one of the entries from Recording #4. The other problem was that our hibernate mapping Recording contained the following entry for mapping a list of SongInstances:

<list-index column="trackListing" base="1" />

Which caused Hibernate to retrieve the SongInstances sequentially by their "track listing." And when the test ran, it deleted the song instance that was set as track #2, causing a null pointer when Hibernate retrieved it. Oops.

So, our problem wasn't really a bug, but a side-effect of our test needing a real test database. Just one more thing to learn I guess.

In other news: we are setting a 'deadline' for feature-completeness by the end of June. Our schedule is progressing pretty well and we should be ready for The Next Step at that time. Yay!

See you next time.

Friday, May 20, 2011

Unknown Entity in Hibernate and other things

Hey everyone,

Let me get this out of the way first: I made a really careless mistake while writing the hibernate mapping files the other day (probably because I should have gone to bed) so I'm going to share it with you for my reference and so you can laugh at me.

What happened was that I had added a mapping for a class (RecordingCommentUserActivity.hbm.xml) and forgot to add a new entry to the hibernate.cfg.xml file. Oops. One of the side-effects was that Hibernate complained about requiring the fully qualified class name, which should have clued me in because you shouldn't ever need it.

The other thing that tripped me up was that a simple select query (using the full path) did not throw any errors in the log (that I saw). So I thought there was something wrong in another aspect of the project.

Of course when I tried to do something real like persist an object to the database, then it complained, giving one of those fun "Unknown Entity" exceptions.

As with a lot of problems, the hardest part was figuring out what was wrong. The fix took a few seconds. And everyone was happy.

In even more happy news, our updated security logic is nearly complete. We now track user activity and prevent duplicate voting of comments/songs/recordings/etc. I've been doing this off of another head on my branch so I can keep my main branch head free of the changes until they are more scrutinized. In the next few days I'll be switching away from security and finishing up an unimplemented voting feature for songs. That's good, because we allocated 1 week for the task on our estimates.

See you next time with more updates.

Tuesday, May 17, 2011

New directions

Hey everyone,

I'm out of school (for a bit) and working at a C# shop for the summer, so you'll probably see some C# issues crop up, although I'm still doing Java web development on the side. I might be rolling out some small WCF-based projects to learn. Maybe rewrite my chemical database project using it. That could be fun.

As for the Recordings project, we came up with a "feature complete" schedule which lists all of the tasks needing completion before we could consider pushing to production. Looks like we still have a few more months left (although we did make pessimistic estimates ... isn't that what you have to do though...)

As for myself, I'm focusing on some revamped security logic. I think I mentioned our very simplified security model in a post about Mockito, but we decided that it needed to be expanded. For example, our users are able to like/dislike (or vote up/down if you want) songs, recordings, and comments on both of those. Before we just limited the user to a certain number of votes per day, but they could still vote more than once.

This time, we're making it so that we track user activity so they can't do that until we delete the user activity entries (every X days or so). This functionality is almost done, in fact, the logic is all there. All that's missing is the Hibernate mappings and the actual data access. Right now the data layer is basically stubbed out. Mostly because writing Hibernate mapping files and data classes is very tedious and not as fun as the rest of it. But we'll get to it eventually.


Stay tune for more exciting programming related updates in the Near Future...

Tuesday, May 10, 2011

Updates.

Hey guys,

It's been a week, and I'm still going through finals. In fact, I have a physical chemistry test that's going to kill me. Expect more updates next week.

Tuesday, May 3, 2011

AJAX and being lazy with tablesorter

Now I love using other peoples' code.

I'm extremely lazy in terms of programming: if someone's written it, I'm going to use it. In fact, the first thing I do (except when I'm reinventing the wheel for learning purposes) is check to see if there's a library for problem X.

An example: we're using the DataTables jQuery plugin to make our tables look pretty. Now, data tables has some nice features:
  • Pagination 
  • Sorting
  • Searching (which updates the results instantly)
  • Easy to integrate (just a one liner) 
All these things make DataTables very attractive. So what's the problem? Well, recently we've been ajax-ifying one of our pages so that it's constantly reloading the same table. For some reason, DataTables doesn't like this (at least with our setup, if it's working for you feel free to share). The end-result is that we lose sorting ability when the AJAX reloads the table. That's a problem.

After spending some time looking for some solutions, we decided to drop DataTables in favor of tablesorter, another jQuery table plugin.

We decided to use tablesorter over DataTables for a couple reasons:
  • It wasn't working with our AJAX setup (as mentioned)
  • At first we were using the other features, but then we stopped using pagination and searching
  • tablesorter integrates just as easily
  • tablesorter is more light-weight (12kb vs 60kb) 
  • tablesorter works for our purposes with no exciting changes (we add a line in our success function to refresh the table) 
So for our purposes, tablesorter was the better option. And the best part is, it let us be as lazy as possible since integrating it took exactly three steps*:
  • download minified js file
  • add to project
  • add two lines of code to existing script files
Very convenient.


* apologies for the multiple bulleted lists, I do kind of like them though.