2017-04-12 2 views
3

Je travaille sur un projet qui doit extraire certaines entités de la base de données et les calculer en utilisant certaines formules. Cette entité contient une date classée mappée à la colonne de date en utilisant le format: yyyy-MM-dd. Une ligne simple échec contenant la date 2009-06-01Spring Data Erreur JPA: InvalidDataAccessApiUsageException: HOUR_OF_DAY: 0 -> 1

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 

J'ai passé quelques heures à creuser dans cette erreur, j'ai finalement trouvé que le Maroc a d'abord passé à l'heure d'été à cette date précise: https://www.timeanddate.com/time/zone/morocco/casablanca, donc le temps 00 n'existe pas . J'ai essayé toutes les solutions proposées ici: https://moelholm.com/2016/11/09/spring-boot-controlling-timezones-with-hibernate/ mais malheureusement, aucune d'elles ne fonctionne!

Répondre

1

Ce qui me donne la solution:

Je débogué le pilote pour savoir ce qui se passait. Il s'avère que les objets Calendar que Hibernate envoie à l'API JDBC sont complètement ignorés. Lorsque le pilote s'exécute dans le mode useLegacyDatetimeCode = true, qui est par défaut. Le pilote obtient l'argument, puis choisit simplement de créer un autre calendrier comme celui-ci: Calendar.getInstance(). L'effet de cela, est que le pilote utilise le fuseau horaire qui est par défaut à la JVM.

Notez que les pilotes JDBC MySQL prennent également en charge un autre argument: serverTimezone = TIMEZONEHERE. Réglez-le sur UTC, passez la configuration Hibernate et vous avez une autre solution. Cette fois, cependant, étroitement lié au pilote spécifique.

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

+0

Le problème de cette solution est que vos dates seront conservées en UTC, ce qui est un problème si vous avez déjà des données dans votre base de données. Je ne sais pas exactement comment les dates déjà enregistrées (dans le fuseau horaire d'origine) seront récupérées, mais je crois que ce sera également un problème. – jfneis

0

Peut-être que vous pouvez l'essayer comme moi.

jdk1.8
mysql lastest

excute sql:

show variables like "%time_zone%";

Puis Posé comme ceci:

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

remplace le serverTimezone par résultat sélectionné.