Thursday, November 11, 2010

Trinidad Date Picker Issue with Daylight Savings Time

Trinidad Date Pickers in the site went haywire just after the DayLight Savings change on November 6. Users who selected a date prior to November 7 would find the input field populating with the previous day selected. The issue is in the javascript in trinidad-impl jar. We are using version 1.2.13. The issue occurred for servers running on the Unix platform and windows. The issue occurred for people using clients with Mac and PC.

I tried setting the time zone in trinidad-config.xml with a number of different options: UTC-8, GMT-8, and Pacific Daylight Time, but no luck.

So I opened the jar:

jar -xvf trinidad-impl.jar

In META-INF\adf\jsLibs the file DateField is the culprit. In the function

_getDayLightSavOffset(a0)

the function gets the client date, and compares the time zone offset to the server time zone offset. For dates after the time change, the offset is 0. For dates prior to the time zone change the offset is always 60. For our app, we always want the value the user selects in the popup to appear in the date field, so I just always return 0 here. I tested with the server date set to various times before and after the time change, and the fix works fine.

Make your change, jar.cf .jar *, and substitute your new trinidad jar.


There are posts related to this, and the problem seems to have been thought to have been fixed previously:

TRINIDAD-1349:_uixLocaleTZ stores the timezone offset of the server at
* the time the page was displayed (Current time), and currentDateTZOffset
* is the timezone offset of client at the current time as well. However,
* the timezone offsets for both client and server can differ for the
* date that was picked due to daylight savings rules. For example, the
* current time is 3 Dec 2008 and the server is in PST (UTC -8) and
* client is in Perth (AWDT, UTC + 9) so the difference is 17h. But if
* the user picks Apr 25, the server is actually in PDT then (UTC-7) and
* the client in AWST (UTC +8) so the difference is actually 15h. The original
* code would subtract 17h, which would cause the resulting date to move
* to the previous day. *

Thursday, May 20, 2010

Performance Improvements for DAO Testing in an ORM environment

In any good size project using an ORM tool such as Hibernate, you are bound to have a good number of DAO classes that encapsulate persistent interactions. Running JUnit tests against your DAO's can take some time with ANT, as a new Session Factory is instantiated for each Unit Test. In a current project the time to run the tests in our DAO package was about three minutes. I found a solution that cut the time to run all the tests down to 40 seconds. The solution : Junit TestsSuite.

The TestSuite instantiates the SessionFactory once, and all the tests reuse the instance. The code:

public class DaoTestSuite extends TestCase{

public static Test suite(){
TestSuite suite = new TestSuite();
suite.addTestSuite(DaoTest1.class);
suite.addTestSuite(DaoTest2.class);

// and so on ... or you could do this reflectively

suite.addTestSuite(DaoTestN.class);


TestSetup wrapper = new TestSetup(suite){
protected DbUtil dbUtil = new DbUtil();

@Override
protected void setUp(){
//Before the suite, we configure the factory
dbUtil.beginConversationThread();
}


@Override
protected void tearDown(){
//After the suite, we ensure the factory is closed
dbUtil.rollbackTransaction();
}
};

return wrapper;
}



The DbUtil class is a standard ORM class that configures the SessionFactory, ensures that a session is open, transaction is active, and provides a means to rollback the transaction.

The Test classes that are added to the suite have the following before and after methods:

protected DbUtil _dbUtil = new DbUtil();


public void setUp() {
_dbUtil.beginConversationThread();
}


public void tearDown() {
_dbUtil.rollbackTransaction();
}


Where the beginConversationThread() call grabs an active session from the factory, or starts the factory if it is not yet configured and running. Since the TestSuite is run in one JVM, the SessionFactory is configured but once.