У меня проблема с сохранением правильных Java LocalDates в базе данных MySQL. Когда я регистрирую дату, она показывает правильную дату, но когда я сохраняю ее для двух разных сущностей (Пользователь и Семья),
Домохозяйство всегда сохраняет ее как на день раньше. (согласованно и объяснимо с помощью разницы часовых поясов), но
Пользователь сохраняет полуслучайную другую дату, которую я не понимаю .
Примеры правильной даты, сохраненных данных домашнего хозяйства, даты сохранения пользователя и разницы в количестве дней между датой пользователя и даты домашнего хозяйства можно увидеть в следующей таблице. На дату 2017-04-01 "случайная" версия для объекта User даже отличается.
Даты верны при запуске локально на мой MacBook Pro, но даты различаются в нашей Java 11 среде разработки или производства Google App Engine. Не могли бы вы помочь мне понять, почему это происходит?
Дата получена с помощью веб-службы REST, которая принимает дату в виде строки YYYY-MM-DD в формате ISO как часть класса UserRegistrationCommand. Затем этот класс преобразует строку в объект LocalDate в своем методе getMoveInDate:
public class UserRegistrationCommand {
...
public String moveInDate;
...
public LocalDate getMoveInDate() {
if(moveInDate == null) {
return null;
}
try {
return LocalDate.parse(moveInDate, DateTimeFormatter.ISO_LOCAL_DATE);
} catch (Exception e) {
return null;
}
}
}
Используя Spring JPA, я затем сохраняю эту дату для объекта User и Household соответственно в базе данных MySQL, где таблицы для эти объекты используют тип данных DATE.
Когда я регистрирую дату до сохранения, она показывает правильное значение. Но когда дата сохраняется в базе данных, таблица User получает дату за много дней, а таблица Household получает дату, которая на один день раньше даты отправки.
(Даты в комментариях к коду ниже относится к первому примеру даты на моем изображении)
Сохранение объекта User:
@Transactional
public User createUser(String email, String password, String firstName, String lastName, String language, Household household, LocalDate moveInDate, String redirectState) {
LOG.debug("Registering user {}, {}, moveInDate: {}", email, household, moveInDate != null ? moveInDate.toString() : "null"); // <-- Logs "Registering user ... moveInDate: 2017-08-01 ..."
[...]
Locale locale = localeProvider.matchAvailableLocale(language);
User user = new User(email, encodedPassword, firstName, lastName, locale, household, moveInDate, NotificationPreferences.defaultPreferences());
user.setRedirectState(redirectState);
Image profilePicture = avatarService.createProfilePicture(user.getNameInitials());
user.setProfilePicture(profilePicture);
return save(user); // <-- calls userRepository.save(user), but date is stored as 2017-07-27
}
Сохранение объекта домашнего хозяйства:
LOGGER.debug("ActivationCodeRegistrationStrategy.register: Setting moveInDate {} for household {} for user {}", cmd.getMoveInDate(), activationCode.getHousehold(), cmd.email); <-- logs "ActivationCodeRegistrationStrategy.register: Setting moveInDate 2017-08-01 ..."
householdService.setMoveInDate(activationCode.getHousehold(), cmd.getMoveInDate()); <-- but a date of 2017-07-31 is saved.
Вызов homeService.setMoveInDate просто устанавливает дату для объекта Household и сохраняет ее в базе данных:
public void setMoveInDate(Household household, LocalDate moveInDate) {
household.setMoveInDate(moveInDate);
householdRepository.save(household);
}