保存到MySQL数据库时如何阻止LocalDate更改

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的时区,所以我怀疑的是,当发生转换,从LocalDateDate,被扣除生产要求的日期之前的日期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)

SEY*_*_91 2

由于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)