There seems to be a problem with the LocalDate in a MySQL database. Depending on the set time zone in the application the persisted date is wrong. LocalDate AFAIK should not be affected by time zones at all. It should just use exactly the date provided and store it, but this is not the case.
This is quite difficult to track down, so I have made a test project that shows the problem in a unit test. Docker is required for this, as it spins up a testcontainers mysql database. Please run the test in TimezoneMysqlBugApplicationTests and have a look at the @BeforeEach and the @Test methods.
You added the timezone identifier to the JDBC (as we did) as well. Does it match the timezone on MySQL server side?
Yes. For the tests, the docker containers should run in UTC time zone and my production database server is also set to UTC, where I can reproduce the issue. But even if they don’t match, this shouldn’t be an issue, because LocalDate should always be a date without a time zone.
The mysql connector is able to return LocalDate, but it is not used - java.sql.date is used.
This uses a time zone for conversion to local date.
The time zone is cached in the server session of the mysql connector.
If you change the time zone “on the fly” (in my case it was application startup, but already too late) the time zone is already cached in the connector.
Thus it will convert to a false LocalDate
org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor uses java.sql.ResultSet#getDate(int) but could use the newer com.mysql.cj.jdbc.result.ResultSetImpl#getLocalDate when used with mysql connector 8
→ You can append cacheDefaultTimeZone=false to the JDBC query string and all tests pass.