debugging


17
Feb 09

Problems with Hibernate

After 8 months of development of a new project with extensive use of Hibernate I can now tell about my experiences with it. In general, Hibernate is a very useful tool. It saves a lot of time, because you don’t have to write SQL queries. If you make changes, you usually don’t have to rewrite queries, because there are only a few of them. The configuration using annotations is simple and powerful (and I personally prefer it to writing mappings in XML). Hibernate is able to generate database tables from mapped classes automatically and even update them as you add new fields to a class. Hibernate caching facilities are very useful. Finally, Hibernate allows to develop database vendor indepentent applications.

But there are few problems which I experienced:

  1. The most frustrating is in fact described in the Hibernate docs. An object returned by session.load() isn’t necessarily an object of the expected class:
    Cat cat = (Cat) session.load(Cat.class, id);  // instantiate a proxy (does not hit the db)
    if (cat.isDomesticCat()) {                  // hit the db to initialize the proxy
        DomesticCat dc = (DomesticCat) cat;       // Error!
        ....
    }
  2. No inheritance mapping for value objects: here is the JIRA issue that never gets fixed, and a workaround.
  3. The strong suggestion in the Hibernate documentation to use a join table for every unidirectional one-to-many association (in the section 2.2.5.3.2.2. “Unidirectional”). Another suggestion is discussed here.
  4. 2nd level caching should be used with caution: after deleting an object the stale version can still stay in cache which can lead to an ObjectNotFoundException. I found no other solution except disabling the 2nd level cache for the class.

3
Sep 07

SQL parameters and query optimization

Few days ago we found out that passing in SQL parameters to a PreparedStatement can affect query optimization when we ran into a problem querying the database from our web app. We constantly got the following error from SQL Server: Adding a value to a ‘datetime’ column caused overflow. In the WHERE clause of the query we had something like DATEADD(month, 2, exam_date) and it went wrong, because there was an invalid exam_date entry in the database table (something like 0095-01-10).

The funny thing is that when we tried to run the very same query in Microsoft Query Analyzer it worked without an error. Then I wrote a short test that queried the database directly using PreparedStatement without Spring and iBatis to localize the problem and found out that when I passed parameters to it the error came, when I put the parameter values into the query itself it didn’t. So it seems that passing the parameters affected the order in which the conditions in the WHERE clause were evaluated: without the parameters another condition was evaluated first so that the errorneous date entry was filtered out before coming to the condition which used DATEADD.