Hibernate, C3P0 and robust database connection handling

Quoting from the official Hibernate docs: "Hibernate's own connection pooling algorithm is, however, quite rudimentary. It is intended to help you get started and is not intended for use in a production system, or even for performance testing. You should use a third party pool for best performance and stability."
And it's all true: you should never (imho not even for development) use the default connection provider.

When working with database connections, it's vital to make sure that the connection is still "valid". Now what could make a connection "invalid"? A number of things. Primarily it's the database server that decides in certain situations that a connection is "hosed" and will reject any real work on it. Therefore you should always check whether your connection is OK or not. How often you do this is up to you.

In a webapp a database connection is usually used only for the duration of the servlet/JSP/etc. execution (ie. just a couple of seconds or split of a second), so it's a good practise to check the connection at the start of every page serve (ie. handling of an URL request) ... or to be efficient, you could check the connection the first time a database request is required during the page request.

In a desktop app your session probably lasts for as long as the app is running, so you've to check the connection on a regular basis.

Spending some time in the database world will pretty fast take you to the concept of connection pools (actually you most probably already met some kind of resource pools before Smile ). Hibernate has it's own implementation, but there're a number of "third party" solutions as well. A connection pool is useful for a number of reasons ... imho the first being that the pool handler is a single point of entry for all connection related work, thus you can have tight control over your connections.

As explained, your connections should always be valid before you do any real work on them and a connection pool provider can make sure that connections handled back to your code are always OK. Unfortunately Hibernate's built in implementation (the default connection provider class is determined through heuristics in org.hibernate.connection.ConnectionProviderFactory, but mostly you'll get org.hibernate.connection.DriverManagerConnectionProvider) does no such thing ... making this one of the reasons for you not to use it for any real work. Thus if your database server decides to make one of your connections invalid (but the server does not close the connection, so you'll never know without explicitly checking!), Hibernate's connection pool will not do anything about it. The invalid connection will just wander from one web session to another and any executed SQL statement will trigger an exception.

This happens eg. with Microsoft SQL Server 2005 when it tries to resolve a deadlock. If two database connections get into a deadlock, SQL server will "kill" one of them, this connection becomes invalid and should be discarded by the client. If you use a connection pool (eg. Hibernate's built in), you should check yourself (before or after a "work session", eg. a page request) whether the connection is still valid (eg. execute a noop SQL statement on the connection, like SELECT NULL in case of SQL Server) and forcefully remove the connection from the pool if it's not OK.

The C3P0 connection (and statement) pooling library is a good place to start looking if you're interested in a proven connection management solution. It's also suggested by the official Hibernate docs and as a matter of fact it's bundled with Hibernate.

Even if you already knew all this, we're all just humans ... well ... the most of us. Smile People make mistakes and an app of yours can easily end up using Hibernate's default connection pool without you noticing. Therefore I suggest you build a check into your app's database connection initialization code (you've a single point of entry for this, right?) to verify the class of the fetched database connection. If it's not C3P0, then log an error or throw an exception to alert the admin (or the user? ... it depends) on the serious configuration flaw. (Note: another approach might be to check the connection provider that is in effect ... and if it's the default Hibernate one, log an error. This way you don't hardcode the use of C3P0 in your app.) Trust me on this: it'll spare you a lot of time and trouble tracking down the cause of mysterious exceptions. I had to learn it the hard way. Sad I assumed that all our projects at the company have been using C3P0 for years, but as a matter of fact, there were a few exceptions. If your framework expects the use of a correct connection pool (ie. you don't check your connections yourself) and it does not ring any bells if the default Hibernate pooling is used, then don't be surprised if it comes back to you biting in the foot at some point. Smile