错误:SqlExceptionHelper:HOUR_OF_DAY:2 -> 3

问题描述 投票:0回答:3

完整错误日志:

2019-09-20 08:35:37.860 信息 1 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat-1].[localhost].[/] : 初始化 Spring DispatcherServlet 'dispatcherServlet'

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

2019-09-20 08:47:29.769 错误 1 --- [nio-8081-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] 在路径 [] 的上下文中抛出异常 [请求处理失败;嵌套异常是 org.springframework.orm.jpa.JpaSystemException:无法执行 询问;嵌套异常是 org.hibernate.exception.GenericJDBCException:无法执行查询] 有根本原因

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

在 java.base/java.util.GregorianCalendar.computeTime(来源未知) 〜[呐:呐]

在 java.base/java.util.Calendar.updateTime(来源未知)~[na:na]

在 java.base/java.util.Calendar.getTimeInMillis(来源未知) 〜[呐:呐]

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

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

编辑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;
}}

编辑2:

OrderRepository.java

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

    @Query("select o from Order o where o.tickets is not null")
    List<Order> ordersWithExistingTickets();
}
java mysql spring date calendar
3个回答
2
投票

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

引起: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();

}

0
投票

从 MySQL 5 迁移到 MySQL 8 连接器后,我们遇到了类似的问题。已验证以下链接

https://confluence.atlassian.com/jirakb/illegalargumentexception-hour_of_day-1063564762.html https://bugs.mysql.com/bug.php?id=96276 https://support.oracle.com/knowledge/Oracle%20Database%20Products/2863969_1.html

问题案例查询:当数据库和Java应用程序都在“美国/太平洋”时区时。

从“2019-03-10 02:00:00”和“2019-03-10 03:00:00”之间的点赞中选择actiondoneon;

+--------------------+

|行动完成 |

+--------------------+

| 2019-03-10 02:27:47 |

+--------------------+

一组 1 行(0.00 秒)

修复案例查询:

mysql> 选择convert_tz(actiondoneon, '美国/太平洋', '美国/太平洋') AS actiondoneon FROM likes WHERE actiondoneon BETWEEN '2019-03-10 02:00:00' AND '2019-03-10 03:00: 00';

+--------------------+

|行动完成 |

+--------------------+

| 2019-03-10 03:00:00 |

+--------------------+

一组 1 行(0.00 秒)

这里我们应用相同时区的convert_tz。 Convert_tz 函数四舍五入到最接近的正确时间戳。

示例:

mysql> SELECT invalid_timestamp、convert_tz(invalid_timestamp、'美国/太平洋'、'美国/太平洋') corrcted_timestamp FROM (SELECT '2019-03-10 02:27:47' invalid_timestamp) 选项卡;

+---------------------+-------------------------- --+

|无效时间戳 | corrcted_timestamp |

+---------------------+-------------------------- --+

| 2019-03-10 02:27:47 | 2019-03-10 03:00:00.000000 |

+---------------------+-------------------------- --+

一组 1 行(0.00 秒)


0
投票

我在这里和其他地方尝试了建议。没有任何结果。 我必须将 MySQL 服务器时间设置为 UTC。按照此处提到的步骤进行操作 -> https://dev.mysql.com/doc/refman/8.0/en/time-zone-support.html 确保您注意“填充时区表”部分,这实际上是我们面临的问题。

© www.soinside.com 2019 - 2024. All rights reserved.