Pho*_*bos 13 mysql jpa-2.0 java-8 hibernate-5.x localdate
使用JPA CriteriaBuilder API 将LocalDate字段(例如“ 2017-09-27”)保存到mySQL Date列时,结果会有所不同(例如“ 2017-09-26”)。
我已经验证我的数据库的时区设置为UTC SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP),结果是“ 00:00:00”。
我在本地测试这一点,我有GMT + 2的时区,所以我怀疑的是,当发生转换,从LocalDate到Date,被扣除生产要求的日期之前的日期1天第2小时(假设LocalDate领域,如没有时间信息的结果将被视为00:00:00。
在这种情况下保存LocalDates的最佳方法是什么?我是否应该按照这里的建议/sf/answers/2082610281/并将所有LocalDate字段显式设置为UTC或类似内容?
我进行了测试,以查看将它们转换为代码时会发生什么,并得到以下结果:
Date convertedDate = Date.valueOf(localDate);
Run Code Online (Sandbox Code Playgroud)
编辑
这是我用来检索数据的代码示例,其中也发生了奇数日期更改。如果我要求提供数据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();
Run Code Online (Sandbox Code Playgroud)
由于LocalDate没有 TimeZone,您可以在数据库模式中将 column_date 映射为 long,并使用AttributeConverterto 转换LocalDate为 long 以避免时区转换问题:
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;
}
}
Run Code Online (Sandbox Code Playgroud)