First, I hope this is the right place for this question. Because I believe this to be a server configuration problem, I wasn't sure if this should go on serverfault.
So we have a spring-mvc webapp running on Tomcat servers and connected to an Oracle database. On one of these pages is a form for the user to fill out where they can enter a set of dates. When I or another developer run the webapp locally on our own machines for testing (still connecting to an external Oracle instance), we have no problems. But now that the webapp has been deployed to two different external Tomcat servers we've noticed problems with the dates.
Somewhere between when the data is submitted from the page (verified using Firefox's TamperData plugin) to the controller and when it is inserted into the database, all of these user inputted dates lose one day. For example, entering 09/02/2010 gets inserted into the table as 09/01/2010. If we submit 09/01/2010, it is inserted as 08/31/2010. These user dates are never explicitly modified in our code.
Those date fields in our spring entity beans are annotated with the following :
@Temporal(value = TemporalType.DATE)
@Column(name = "START_DATE", nullable = false, length = 7)
@DateTimeFormat(pattern="MM/dd/yyyy")
Also, at some point during the data processing. we set up a field with the current date:
obj.setActivityDate(new Date());
Those activity dates are unaltered and always come through with the correct date when we check the database.
Like I said, we're unable to reproduce this error when we run the app locally, so we (want to) believe the problem is with one of the other Tomcat servers that we have deployed to. Has anyone ever run into a problem like this before, or do you have any ideas of what could be causing it?
UPDATE:
So I took the timezone hints and it sent us off in the right direction, but we're still not there yet. I went into my entity bean, changed the field from java.util.Date to a jodaTime DateTime object, like this:
@Column(name = "START_DATE", nullable = false, length = 7)
@DateTimeFormat(pattern="MM/dd/yyyy")
@Type(type = "org.joda.time.contrib.hibernate.PersistentDateTime")
private DateTime startDate;
After making adjustments to handle the new type, I ran some more tests and we can now see that the date 09/01/2010 is being inserted into the database as 08/31/2010 8:00:00 pm. I think that the TemporalType=DATE may have been forcing a truncation somewher开发者_如何学Pythone along the line, which is why we didn't see the timestamp before. Here are the timezone settings that I know of (our office is in Virgina, US-Eastern):
- Tomcat is launched with the timezone set to EST5EDT.
- The linux servers that host Tomcat are set to EST.
- The linux server that hosts the Oracle instance is set to EST.
- The Oracle database timezone is set to UTC (+00:00)
- The timezones for the user sessions in Oracle are (currently) set to -04:00.
If this was all there was to it, then I could understand why a user input date (with no explicit time zone) would be translated in the database as -04:00. But we still cannot reproduce the problem locally on our own machines (Windows 7 and Fedora, both set to US/Eastern). I've tried manipulating dates to force a time zone, but it always comes through as 8:00pm. Here is the log output from two separate runs:
Storing date startDate: 2010-09-01T00:00:00.000
Storing date startDate: 2010-09-01T00:00:00.000-04:00
Each of those dates went from Tomcat (with Spring/Hibernate) into the database as 08/31/2010 8:00PM when run on the external Tomcat servers, but inserted as 09/01/2010 12:00AM when run locally. The only good thing to come out of this so far is that the dates are re-translated when pulled from the database and displayed to the user on the screen, so that it matches what they originally typed in.
In order to be able to develop consistently, we need to know what setting we could be missing on our local machines that is avoiding this problem. We're currently using Tomcat 6.0.20, bundled with NetBeans to run locally.
As an idea:
Something to do with time zones. You submit a datetime value with one timezone information, the database is configured to use another timezone so it's converting your dates on-the-fly.
A few hours can already make a difference. You insert a 09/01/2010 01:55, it can easily become 08/31/2010 23:55.
精彩评论