In a response to my previous rambling, Benoit was kindly enough to point me at a severely under-documented Hibernate configuration property:
hibernate.jdbc.wrap_result_sets = true
I did some performance tests with getting some date out of our database and look and behold:
Method Time(ms) Count oracle.findColumn(String) 2793 19292 oracle.getLong(String) 1630 12836 oracle.getBigDecimal(String) 397 1068 oracle.getInt(String) 258 2152 oracle.getString(String) 192 1068 oracle.getTimestamp(String) 190 1068 oracle.getDouble(String) 101 1068 oracle.getBoolean(String) 21 32 hibernate.ResultSetWrapper.findColumn(String) 409 19292 hibernate.ResultSetWrapper.getLong(String) 225 12836 hibernate.ResultSetWrapper.getInt(String) 63 2152 hibernate.ResultSetWrapper.getBigDecimal(String) 52 1068 hibernate.ResultSetWrapper.getDouble(String) 21 1068 hibernate.ResultSetWrapper.getTimeStamp(String) 21 1068 hibernate.ResultSetWrapper.getString(String) 20 1068 hibernate.ResultSetWrapper.getBoolean(String) 3 32
If you use Oracle in combination with Hibernate, I urge you to use the setting Benoit kindly provided (your mileage may vary though).
You’re welcome
LOL, thanks very much for this quick fix. You’re a man of few words but great deeds!
Pretty interesting find, I’ve worked with hibernate for quite a while now and never knew about this feature. The only thing I’d question is how much does this increase the memory foot print of an application. It looks like for every entity you have mapped in your application you will have a cache (map) of column name to index number. This is probably ok, unless your application has thousands or entities. Either way, nice find.
Hibernate seems to maintain this cache per resulset through the loader (see org.hibernate.jdbc.ResultSetWrapper and org.hibernate.jdbc.ColumnNameCache)
For others (good ?) jdbc implementations this trick is done inside the driver…
Pingback: Optimizing Oracle and Hibernate performance « Rambling about…