This problem is very widely seen. For example, here are some remarks by Martin Fowler.
The underlying issue is that Java's date classes treat dates/times like quantities in physics - representations of a specific, immutable instant in time.
The problem is that this does NOT match how most people think casually about time. In typical discourse, people think of '2009-08-01 18:00' as fixed idea. The problem is that there is no time zone attached to such a representation; hence, it does not actually represent a specific instant.
This is a continuing source of confusion in many applications. While Java always uses timezones (either implicitly or explicitly), databases don't usually store time zone information along with dates/times. Hence, Java must ADD an assumed time zone when it creates a Date object. This will be done by a JDBC driver when it converts the value to a Date object. If such code runs on a server, then the assumed time zone often doesn't match that used by the client/end user.
The only answer is to make sure your Java code uses a 'standard' time zone.