Monday, November 23, 2009

Why did Hibernate do that?!

As i have mentioned in the past, i am not a fan of Hibernate and other ORM tools that generate the SQL for me. This week i have yet another reason for not being willing to consider changing my opinion.

Unbeknownst to me, in our Hibernate application when we were using an “update” to update the one or two columns we change during the regular running of our application, we discovered that actually the update was updating all fields as well as cascading to additional tables joined to this object, which included a CLOB that was getting and update called on it and causing a lot of overhead.

After being warned by our DBA’s to fix ASAP, our next step was to reproduce the problem in our environment so we quickly turned on the “hibernate.show_sql” property to see our SQL. And before we even got to the issue we were looking to solve, we discovered another perplexing Hibernate-ism. We found that when we were doing an initial load or find by id, we were seeing an update happening to the record at the same time as the find/load!

After some fishing around the internet, we understood why this was happening. It was because one of out getters was changing the value from null to something more meaningful, as we see here. When we altered the code to not have this happen, then that update was prevented.

Now onto the problem we were meant to deal with (isn’t always the case that this happens!). After not seeing the results we were hoping for through setting some of the parameters mentioned in various forums (dynamic-update and select-before-update) in an attempt to have our Hibernate “update” not cascade unnecessarily through all the objects and update them all, we settled on a very iBatis like solution. We created the update ourselves so that we know what we are updating, i.e:

String hql = "update myTable set field1 = :field1 where id = :id";
Session session = SessionFactoryUtils.getSession(getSessionFactory(), false);
query = session.createQuery(hql);
query.setString("field1", myObj.getField1());

Of course, once you are doing this, you have lost the “advantage” of Hibernate.

No comments:

Post a Comment