0

The Problem

I am facing issues with a LocalDate being fetched incorrectly from the database.

I save a date, in this case 2020-06-04, and when I retrieve it from the database I get 2020-06-03, so minus one day. The following screenshot from IntelliJ visualizes the problem:

IDE Screenshot

I enabled Hibernate's logging to verify that it is not a Jackson deserialization problem. The logs state that the date was inserted as 2020-06-04 as shown below:

2020-05-21 14:55:55.587  INFO 16608 --- [           main] n.t.d.l.l.SLF4JQueryLoggingListener      : 
Name:dataSource, Connection:8, Time:1, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["insert into voucher (created_at, version, application_object_id, application_type, code, max_usages, usages, valid_until, value, voucher_creator_id, voucher_type) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"]
Params:[(2020-05-21 12:55:55.5468081,0,1,SPORTS_FACILITY,WINTER30,NULL(INTEGER),0,2020-06-04,30,NULL(BIGINT),RELATIVE)]

The Configuration

Spring Boot 2.3.0.RELEASE
Hibernate 5.4.15.Final
MySQL 5.7

application.properties:
- spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useLegacyDatetimeCode=false&zeroDateTimeBehavior=convertToNull
- spring.jpa.properties.hibernate.jdbc.time_zone=UTC

I also have class that sets the JVM timetone as follows:

@Configuration
@Slf4j
public class TimeZoneConfiguration {

    @PostConstruct
    void setDefaultTimeZone() {
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
        log.info("Spring boot application running in timezone UTC, now is: {} ", LocalDateTime.now());
    }
}

The table was created with the following SQL script:

create table voucher
(
    id                    bigint      not null auto_increment,
    application_object_id bigint,
    application_type      varchar(40) not null,
    code                  varchar(30) not null,
    max_usages            integer,
    usages                integer     not null,
    valid_until           date        not null,
    value                 integer     not null,
    voucher_creator_id    bigint,
    voucher_type          varchar(40) not null,
    created_at            datetime(6) not null,
    version               integer     not null,
    primary key (id),
    foreign key (voucher_creator_id) references vendor (id)
) engine = InnoDB;

The Voucher entity looks as follows (Getters, Setters, etc. omitted for brevity):

@Entity
public class Voucher {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name = "native", strategy = "native")
    private Long id;

    @Column(nullable = false, updatable = false)
    @CreationTimestamp
    private LocalDateTime createdAt;

    @Version
    private int version;

    @Column(updatable = false)
    private Long applicationObjectId;

    @Column(nullable = false, updatable = false)
    @Enumerated(EnumType.STRING)
    private ApplicationType applicationType;

    @Column(length = 30, nullable = false, updatable = false)
    private String code;

    @Column(updatable = false)
    private Integer maxUsages;

    @Column(nullable = false)
    private int usages = 0;

    @Column(nullable = false, updatable = false)
    private LocalDate validUntil;

    @Column(nullable = false, updatable = false)
    private int value;

    @JoinColumn(name = "voucher_creator_id", updatable = false)
    @ManyToOne(fetch = FetchType.LAZY)
    private Vendor voucherCreator;

    @Column(nullable = false, updatable = false)
    @Enumerated(EnumType.STRING)
    private VoucherType voucherType;

}

Edit

I have recently switched to version 8.0.20 of the mysql-connector-java library. After switching back to version 8.0.19 everything worked as before.

In my opinion, closing question was unjustified because the reason was that it is a duplicate. The links to the "duplicates" contained problems where the date was saved with an offset, not retrieved. Therefore, I suggest that this question is reopened so that other people might be able to benefit from this finding!

times29
  • 2,782
  • 2
  • 21
  • 40
  • Please remove the UTC from mysql `spring.datasource.url=jdbc:mysql://localhost:3306/test?useLegacyDatetimeCode=false&zeroDateTimeBehavior=convertToNull` just keep it in spring default timeZone – Hussein Akar May 21 '20 at 13:39
  • @HusseinAkar thank you for your suggestion. I added it recently hoping it would fix the problem, but it makes no difference! – times29 May 21 '20 at 19:07
  • If you didnt get an answer until tomorrow night will make sure to replicate your code and help .. best luck – Hussein Akar May 21 '20 at 23:48

0 Answers0