Java Chatter and Random Nagging

Tuesday, May 15, 2007

Java Calendar Bug ?! Setting before Getting

Saturday Fever
This one kept me puzzling for quite a while. I was trying to loop over every saturday of the year to fill in a weekend for my Human Resource Application. I had a tested convenience method that returned the first day of a given year and my first try was to use this method and afterwards set the day of week to saturday. The extracted bugcode looks like this :

public class BugWhileLookingForTheFirstSaturdayOfYear {
public static void main(String[] args) {
strange();
strangeFixed();
}

private static void strange() {
Calendar calendar = firstDayOf2007();

calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
System.out.println(calendar.getTime());
}

private static void strangeFixed() {
Calendar calendar = firstDayOf2007();

//Adding this line solves it !!
calendar.get(Calendar.YEAR);

calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
System.out.println(calendar.getTime());

}

private static Calendar firstDayOf2007() {
Calendar calendar = Calendar.getInstance();
calendar.set(2007, Calendar.JANUARY, 1, 0, 0);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar;
}
}

This generates the following lines :

Sat Jan 20 00:00:00 CET 2007
Sat Jan 06 00:00:00 CET 2007


Strange, right ? But apparently this behavior is "Works As Designed" ! When digging into the java.util.Calendar class, things become a lot more clear. Apparently, simply using set(int, int) for setting a certain property does not immediately set the time of the calendar object to the given value. It only computes this value when calling the add(int, int) or get(int) method. Thus setting the DAY_OF_WEEK cancels out our setting of the DAY_OF_MONTH in calendar.set(2007, Calendar.JANUARY, 1, 0, 0).

You can figure out that the reason why we get the wrong value of Jan 20th is because of the fact that today is the 16th of May. The next saturday counting from the 16th of January is indeed the 20th of January. The problem can easily be solved by calling a get(int) before using set(int) again, but it took me a complete hour to figure out this Calendar headache.

Related bug (and Closed Correctly) : http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6212052

Wednesday, May 09, 2007

Crazy Hibernate Error Messages

It could be because of my limited knowledge of Hibernate, but Hibernate's error messages are a real mystery to me. For a framework, so widely accepted by both the community and the industry, I find their error messages shown to the user (programmer) very disturbing. My latest problem had everything to do with the following error:

org.springframework.orm.hibernate3.HibernateSystemException: could not set a field value by reflection setter of hrutil.model.Employee.workYears; nested exception is org.hibernate.PropertyAccessException: could not set a field value by reflection setter of hrutil.model.Employee.workYears

Not an easy one, I'll tell you. Yesterday, I've surfed the internet for about half an hour and still nothing so I went to sleep with this "unsatisfied programming problem" feeling. After some trial-and-error, I finally found my problem in the mapping file. It appeared that workYears was a SortedSet and I forgot to add sort="natural " to the workYears property.

<set name="workYears" lazy="true" cascade="all-delete-orphan" table="EMPLOYEES_WORKYEARS" sort="natural">
</set>


It works like a dream again now, but with error messages like this, something tells me that it won't be long till my next Hibershite (as a former colleague called it) frustration shows.