Excellent info Juergen, thanks. Over the last year we too have encountered the exact same problems that you describe with the MySQL driver, both with and without Commons DBCP, although usually worse with it. A big +1 from me on Juergen's suggestion to add a max-time-to-live setting in DBCP. Until then, I'll withold my hope on using Tomcat JNDI data sources for MySQL connections. All it takes is a single Memorial weekend of application inactivity to see my app erroring out on the connection(s).
The only reason you see this issue with MySQL is because the server has a forced-disconnect after 8 hours of idle time (which is of course configurable).
Either configure your connection pool to not let connections sit idle for more than 8 hours (which is a resource drain, unfortunately DBCP has no easy way to do this, as is already covered in this thread), or configure "wait_timeout" on the server to be something higher, like 2^32 if you care more about connections living a long time rather than claiming resources while they're idle.
Most people who run with MySQL and JDBC in heavy production use connection pools that support max idle time scenarios, and they only let connections go idle for a few seconds. It only takes a few milliseconds to setup a new MySQL connection, so you're not saving any _time_ by using a connection pool (what you _are_ doing is throttling resource usage).
Note that you'd have the _exact_ same problems with any other vendors' JDBC driver if someone happened to pull your network cable, or restart the database. You just happen to notice it more with MySQL because of the server's forced disconnect (designed to deal with poorly written PHP apps and C programs which sometimes didn't clean up their connections when they were done with them).
In any case, there is absolutely no guarantee that a connection pulled from a connection pool will be live, which is why you need to deal with SQLExceptions if you want database connection failures to be transparent to your users. The JDBC specification doesn't specify that, and if you think it through, there's no way that guarantee could be made, due to transactional recovery requirements (unless you wanted a full-blown logging transaction manager on the _client_ side that could replay transactions from a failed connection).