Archive for the ‘hibernate’ Category
Some weeks ago I wrote down some notes for making Oracle work harder and faster with hibernate.
Those notes were collected from several places on the Internet and are supposed to help.
But they didn’t. Not for us.
Good news is that we found the problem of the bad performance and fixed it… it was all caused by foreign key integrity checks.
We got our first clue when the sysadmin detected a lot (say, 12 or so) open cursors for a simple update sentence.
We were using defaults for most of the hibernate settings and even when the update was intended to only change one column, the sql sentence set all the fields in the table for the affected row.
And Oracle fired all the checks.
I’m not sure why Oracle does not optimize this by first checking if the value has changed (if it hasn’t, then the constraints are forcedly valid), but the solution was simple… don’t update more than you need.
I have a new friend and it is called
@org.hibernate.annotations.Entity(dynamicUpdate=true). There is some (extremely brief) documentation on the hibernate annotations reference and javadocs. Of course you can also use it in the
hbm files if XML is your thing.
Just in case you did not guess it, this only updates dirty properties of your objects (i.e. those that you updated after retrieving it from the database).
This has potential caveats if another transaction somehow updates your object, since the database state will be different that what you expect. To the best of my understanding this can only happen with detached objects in any reasonable isolation level… and you should reload the state from database in that case.
Well, so that was it… too many constraints on a table and updating more columns than needed. Updating only the affected columns increased performance to where we expected: better than the mysql-based prototype.
I’ve collected the following bits of information regarding the tunning of Oracle when used with Hibernate performance… it might help someone (and I need to write it down somewhere I won’t loose when moving from a desk to another!).
The following properties should be set:
# See http://martijndashorst.com/blog/2006/11/28/hibernate-31-something-performance-problems-contd/
# NOTE: See http://opensource.atlassian.com/projects/hibernate/browse/HHH-3359
hibernate.jdbc.wrap_result_sets = true
# See http://www.hibernate.org/120.html#A10
hibernate.dbcp.ps.maxIdle = 0
hibernate.c3p0.max_statements = 0
# Everything else comes from http://docs.codehaus.org/display/TRAILS/DatabaseConfigurations
# The Oracle JDBC driver doesn't like prepared statement caching very much.
# or batching with BLOBs very much.
I have not tested the performance difference… just collected the information.
Let me know if you know more tricks!
Update: Added a warning about a memory leak in current hibernate, thanks to dfernandez.
Update 2: Statement caching for Oracle can be enabled directly on the datasource implementation. See this article.
I while back, I read The Mythical Man-Month. The data in chapter 8 of the book (which is by no means recent) points out that the average productivity for a developer, measured in debugged lines of code per year is almost constant.
The interesting part here is that it is constant even when changing languages.
The data compares LOC written in low level machine code and those written in a high level language (PL/I). Because every line in PL/I was on average generating 5 low level instructions, this mean improving developper productivity by a factor of 5.
Fast forward 32 years… and now I’m here wondering if the rule still applies.
I guess the answer is yes, and that’s why everyone is so happy with languages like Ruby and concepts like convention over configuration, which allow you to write less.
But then… Spring must be a huge productivity boost, since it is quite coarse grained. You’re not avoiding code… you’re doing more with less code. Same thing for Hibernate.
Less LOC, more function.
To be fair… this is more related to component reuse (called “buy versus build” in the book) than to higher level languages.
Then there are the DSL (Domain Specific Languages) that are starting to pop up everywhere. Specific high level languages for specific problems (like configuration, business rules, etc…). Those should really cause a big impact in productivity if they can be used in a significant part of a project. I’m under the impression that DSLs are used for relatively small parts of a system (maybe BPEL would be the only one able to have a wider scope).
So why aren’t these new languages/frameworks used everywhere? Why are they not taught at computer science faculties?
It’s related to the intellectual load imposed on the developer.
Lower level languages can do any thing with a reduced set of commands (functions, operations… you name it). The developer needs to know very little thing about the language but needs to figure out how to do every little thing. Just imagine how a simple hello world program would look in assembler.
In the other hand, higher level languages require knowledge about lots of commands and features. Put in the mix a wide collection of extensions (or libraries) and integration with other high level languages, and the intellectual overhead is just barely manageable.
Maybe at this point is where we start creating standards. J2EE is not the best of the options (JSF, EJB…) but is a standard. A developer can learn it and have a pretty good grasp of everything without being overloaded with too much information.
However, most companies are using other kind of tools, like Spring or Hibernate (although Hibernate now can be used with JPA, so it can be seen as a standard). And every project/company uses a different presentation framework (we have plenty to choose from in the java world).
And then there is Eclipse RCP, Grails, Jython… and outside the java world you always need some Bash, Perl (at least Perl regexps)…All this tools make something easier and faster, but they add to the pile of knowledge a developer requires to do his job.
Under this stress, how can we remain productive and still be able to create working solutions in our jobs?
I don’t know. But we certainly do.
And from time to time, they are not only working… they are good!
I must admit that I had never tried Appfuse 1.0 because of my laziness. It required me to download something, install it somewhere and then run ant on it… too many things just for giving it a test ride.
But the new 2.0 version is just a piece of cake. No installation needed. Just use your Maven tool and generate a template project from scratch. There are several templates available, depending on your particular taste.
Let me clarify that, even when I call them “templates”, what you get is a working webapp (you can even run it from the command line, without installing anything else). The webapp does not do much… but is actually good looking and provides a log-in form and user management features (two things you will likely need).
By now, only milestone 2 has been released. Milestone 3 will come later and, at last, 2.0… in “late” 2007.
I expect (time permitting) to dig a little deeper on it… And you should too.
It is focused on simplying the most usual cryptographic tasks (like encryption and hashing) with a plus: it is designed with easy integration in mind.
If using Hibernate, you can declaratively configure encryption for your persistent entities, and it is also easy to manage through spring.