Spring Data JPA 错误:InvalidDataAccessApiUsageException:HOUR_OF_DAY:0 -> 1

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

我正在开发一个项目,该项目必须从数据库中提取一些实体,并使用一些公式计算它们。该实体包含映射到日期列的归档日期,使用格式:

yyyy-MM-dd
。包含日期的单行失败
2009-06-01

org.springframework.dao.InvalidDataAccessApiUsageException: HOUR_OF_DAY: 0 -> 1; nested exception is java.lang.IllegalArgumentException: HOUR_OF_DAY: 0 -> 1
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:384)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:491)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy107.findFirst2ByBeginnigOfYearIsNull(Unknown Source)
at com.peaqock.service.VlAnService.computeNotCalculatedVlans(VlAnService.java:156)
at com.peaqock.service.VlAnService$$FastClassBySpringCGLIB$$2dad4910.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
  Caused by: java.lang.IllegalArgumentException: HOUR_OF_DAY: 0 -> 1
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2829)
at java.util.Calendar.updateTime(Calendar.java:3393)
at java.util.Calendar.getTimeInMillis(Calendar.java:1782)
at com.mysql.cj.jdbc.io.JdbcDateValueFactory.createFromDate(JdbcDateValueFactory.java:66)
at com.mysql.cj.jdbc.io.JdbcDateValueFactory.createFromDate(JdbcDateValueFactory.java:39)
at com.mysql.cj.core.io.BaseDecoratingValueFactory.createFromDate(BaseDecoratingValueFactory.java:46)
at com.mysql.cj.core.io.BaseDecoratingValueFactory.createFromDate(BaseDecoratingValueFactory.java:46)
at com.mysql.cj.core.io.MysqlTextValueDecoder.decodeDate(MysqlTextValueDecoder.java:66)
at com.mysql.cj.mysqla.result.AbstractResultsetRow.decodeAndCreateReturnValue(AbstractResultsetRow.java:70)
at com.mysql.cj.mysqla.result.AbstractResultsetRow.getValueFromBytes(AbstractResultsetRow.java:225)
at com.mysql.cj.mysqla.result.ByteArrayRow.getValue(ByteArrayRow.java:78)
at com.mysql.cj.jdbc.result.ResultSetImpl.getNonStringValueFromRow(ResultSetImpl.java:658)
at com.mysql.cj.jdbc.result.ResultSetImpl.getDateOrTimestampValueFromRow(ResultSetImpl.java:671)
at com.mysql.cj.jdbc.result.ResultSetImpl.getDate(ResultSetImpl.java:816)
at com.mysql.cj.jdbc.result.ResultSetImpl.getDate(ResultSetImpl.java:827)
at org.hibernate.type.descriptor.sql.DateTypeDescriptor$2.doExtract(DateTypeDescriptor.java:76)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:238)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:234)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:224)
at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:300)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2738)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1729)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1655)
at org.hibernate.loader.Loader.getRow(Loader.java:1544)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:727)
at org.hibernate.loader.Loader.processResultSet(Loader.java:972)
at org.hibernate.loader.Loader.doQuery(Loader.java:930)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336)
at org.hibernate.loader.Loader.doList(Loader.java:2617)
at org.hibernate.loader.Loader.doList(Loader.java:2600)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2429)
at org.hibernate.loader.Loader.list(Loader.java:2424)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1326)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:87)
at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:606)
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:483)
at org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:372)
at com.sun.proxy.$Proxy122.getResultList(Unknown Source)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:121)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:85)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 19 common frames omitted

我花了几个小时挖掘这个错误,我终于发现摩洛哥在这个特定日期首先切换到夏令时:https://www.timeanddate.com/time/zone/morocco/casablanca,所以时间

 00
不存在。我尝试了这里建议的所有解决方案:https://moelholm.com/2016/11/09/spring-boot-controlling-timezones-with-hibernate/但不幸的是它们都不起作用!

spring-boot spring-data spring-data-jpa date
5个回答
5
投票

这给了我解决方案:

我调试了驱动程序以了解发生了什么。事实证明,Hibernate 发送到 JDBC API 的日历对象被完全忽略。当驱动程序在 useLegacyDatetimeCode=true 模式下运行时,这是默认的。驱动程序获取参数 - 然后只需选择创建另一个日历,如下所示:Calendar.getInstance()。其效果是驱动程序使用 JVM 默认的时区。

请注意,MySQL JDBC 驱动程序还支持另一个参数:serverTimezone=TIMEZONEHERE。将其设置为 UTC,跳过 Hibernate 配置,您就有了另一个解决方案。然而,这一次,与特定的驱动程序紧密相连。

我的解决方案是:

jdbc:mysql://<ip>/<db>?useSSL=false&&serverTimezone=UTC&useLegacyDatetimeCode=false


0
投票

也许你可以像我一样尝试一下。

jdk1.8
mysql 最新

执行sql:

show variables like "%time_zone%";

然后这样设置:

db.url=jdbc:mysql://ip:point/database?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&serverTimezone=&useSSL=false&useLegacyDatetimeCode=false

用选择结果替换

serverTimezone


0
投票

我猜您的问题与

java.util.Date
有关。您可以使用
java.time.LocalDate
来轻松解决。


0
投票

如果您不想重新启动

mysql server
,请尝试将
mysql-connector-java
退回到
version5.1.49


0
投票

您可以在数据库中找到那些“不可能的日期”。下面是巴西时区的示例(DST 周期的历史开始日期):

select id, data from email where
(data between '2018-11-04 00:00:00' and '2018-11-04 01:00:00') or
(data between '2017-10-15 00:00:00' and '2017-10-15 01:00:00') or
(data between '2016-10-16 00:00:00' and '2016-10-16 01:00:00') or
(data between '2015-10-18 00:00:00' and '2013-10-18 01:00:00') or
(data between '2014-10-19 00:00:00' and '2013-10-19 01:00:00') or
(data between '2013-10-20 00:00:00' and '2013-10-20 01:00:00') or
(data between '2012-10-21 00:00:00' and '2012-10-21 01:00:00') or
(data between '2011-10-16 00:00:00' and '2011-10-16 01:00:00') or
(data between '2010-10-17 00:00:00' and '2010-10-17 01:00:00')

我通过在找到的日期上添加一小时解决了这个问题。

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