如何在保存到mySQL数据库时阻止LocalDate更改
问题描述:
使用JPA CriteriaBuilder API将字段(例如'2017-09-27')保存到mySQL Date
列时,结果不同(例如'2017- 09-26' )。如何在保存到mySQL数据库时阻止LocalDate更改
我已验证我的数据库的时区设置为UTC,使用SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP)
作为结果'00:00:00'。
我在本地测试这个,我有GMT + 2的时区,所以我怀疑当转换发生从LocalDate
到Date
时,2个小时被扣除并且在请求日期前1天产生一个日期假设LocalDate
领域,因为它有没有时间信息的结果,被视为00:00:00。
什么是拯救LocalDates在这种情况下,最好的方法是什么?我应该遵循的建议这里https://*.com/a/29751575/3832047并明确地设置所有LocalDate字段为UTC或类似的东西?
我跑了一个测试,看看会发生什么在代码转换时,他们得到了以下结果:
Date convertedDate = Date.valueOf(localDate);
编辑
下面是代码的一个例子,我用它来检索数据,奇数日期也发生变化。如果我要求2017-06-27
的数据,我会收到2017-06-26
的结果。
CriteriaBuilder criteriaBuilder = sessionFactory.getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(HorseAndTrailerRequest.class);
Root<HorseAndTrailerRequest> criteria = criteriaQuery.from(HorseAndTrailerRequest.class);
ParameterExpression<LocalDate> effectiveDateParameter = criteriaBuilder.parameter(LocalDate.class);
criteriaQuery.select(criteria)
.where(
criteriaBuilder.equal(criteria.get("effectiveDate"), effectiveDateParameter)
);
TypedQuery<HorseAndTrailerRequest> query = sessionFactory.getCurrentSession().createQuery(criteriaQuery);
query.setParameter(effectiveDateParameter, date);
return query.getResultList();
答
由于LocalDate
没有的时区,你只要能在你的数据库模式映射column_date,并使用AttributeConverter
到LocalDate
转换为长,以避免时区转换问题:
import javax.persistence.Converter;
import java.time.LocalDate;
import javax.persistence.AttributeConverter;
@Converter
public class LocalDateToLong implements AttributeConverter<LocalDate, Long> {
@Override
public Long convertToDatabaseColumn(LocalDate date) {
if (date != null) {
long epochDay = date.toEpochDay();
return epochDay;
}
return null;
}
@Override
public LocalDate convertToEntityAttribute(Long epochDay) {
// TODO Auto-generated method stub
if (epochDay != null) {
LocalDate date = LocalDate.ofEpochDay(epochDay);
return date;
}
return null;
}
}
的Java'LocalDate'对象不会存储时间或时区信息(请参阅[Javadoc](https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html)],我怀疑是否有其他内容。 –
您可以尝试运行以下命令来确认你的MySQL服务器时区:'SELECT @@ system_time_zone,NOW(),UTC_TIMESTAMP()' –
@TimBiege leisen结果是'UTC | 2017-09-27 11:28:51 | 2017-09-27 11:28:51'。 – Phobos