错误:SqlExceptionHelper:HOUR_OF_DAY:2 -> 3

Far*_*hti 5 java mysql spring calendar date

完整的错误日志:

2019-09-20 08:35:37.860 INFO 1 --- [nio-8081-exec-1] oaccC[Tomcat-1].[localhost].[/] : 初始化 Spring DispatcherServlet 'dispatcherServlet'

2019-09-20 08:47:29.726 错误 1 ​​--- [nio-8081-exec-5] ohengine.jdbc.spi.SqlExceptionHelper:HOUR_OF_DAY:2 -> 3

2019-09-20 08:47:29.769 错误 1 ​​--- [nio-8081-exec-5] oaccC[.[.[/].[dispatcherServlet] : Servlet [dispatcherServlet] 的 Servlet.service() 与上下文路径[]抛出异常[请求处理失败;嵌套异常是 org.springframework.orm.jpa.JpaSystemException:无法执行查询;嵌套异常是 org.hibernate.exception.GenericJDBCException: could not execute query] 与根本原因

java.lang.IllegalArgumentException: HOUR_OF_DAY: 2 -> 3

在 java.base/java.util.GregorianCalendar.computeTime(Unknown Source) ~[na:na]

在 java.base/java.util.Calendar.updateTime(Unknown Source) ~[na:na]

在 java.base/java.util.Calendar.getTimeInMillis(Unknown Source) ~[na:na]

这个问题已经在Java 级别解决了,但是我如何在mysql级别避免它。
事实上,查询甚至没有日期或时间。

@Query("select o from Order o where o.tickets is not null")
List<Order> ordersWithExistingTickets();
Run Code Online (Sandbox Code Playgroud)

编辑 1:

订单.java

@Entity
@Data
@Table(name="orders")
public class Order {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "PK")
private Long pk;

@Column(name = "createdTS")
private ZonedDateTime creationTime;

@Column(name = "tickets")
private String tickets;

public String getTickets() {
    return tickets;
}

public void setTickets(String tickets) {
    this.tickets = tickets;
}}
Run Code Online (Sandbox Code Playgroud)

编辑2:

订单仓库.java

@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {

    @Query("select o from Order o where o.tickets is not null")
    List<Order> ordersWithExistingTickets();
}
Run Code Online (Sandbox Code Playgroud)

Arc*_*ano 3

原因是有一个日期时间字段(不是时间戳)在您的时区不可用。所以无法正确转换。

引起原因:java.lang.IllegalArgumentException:HOUR_OF_DAY:2 -> 3 在java.base/java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2826) 在java.base/java.util.Calendar.updateTime(Calendar.java) :3428)在java.base / java.util.Calendar.getTimeInMillis(Calendar.java:1812)在com.mysql.cj.result.SqlTimestampValueFactory.localCreateFromTimestamp(SqlTimestampValueFactory.java:108)

有关信息https://confluence.atlassian.com/jirakb/illegalargumentexception-hour_of_day-after-changing-mysql-database-timezone-1063564762.html

但通常您必须找到错误记录并将其从数据库中删除或更新。

假设您正在使用 JOOQ 或有权执行此操作(因为使用 JPA 查询会导致问题)。这是我在 JUnit 集成测试中放入的代码片段

@Test
void ensureDatesAreOkayDuringDaylightSavings() {
  var fallbackDayClauses = IntStream
    .range(2000, LocalDate.now().getYear() + 1)
    .mapToObj(year ->
      LocalDate.ofYearDay(year, 1)
        .withMonth(3)
        .with(TemporalAdjusters.next(DayOfWeek.SUNDAY))
        .with(TemporalAdjusters.next(DayOfWeek.SUNDAY))
        .atTime(1, 59, 0)
    )
    .map(startDateTime -> 
        MYDB.CREATED_ON.between(
          startDateTime, 
          startDateTime
            .plusHours(1)
            .plusMinutes(2)))
    .collect(Collectors.toSet());

  var potentialProblemIds = dsl.select(MYDB.ID)
    .from(MYDB.TABLE)
    .where(or(fallbackDayClauses))
    .fetch(MYDB.ID);

  assertThat(potentialProblemIds)
    .isEmpty();

}
Run Code Online (Sandbox Code Playgroud)