【问题标题】:Spring Boot -- Can't use LocalDateTime with GraphQL filter librarySpring Boot——不能将 LocalDateTime 与 GraphQL 过滤器库一起使用
【发布时间】:2023-02-09 04:55:46
【问题描述】:

长话短说,我有一个自定义过滤器对象,用于转换为 JPA 查询。

// env is a DataFetchingEnvironment
FilterExpression filterExpression = builder.args(env.getArguments()).build();
Specification<BaseModel> specification = filterExpression.getExpression(ExpressionFormat.JPA);

堆栈跟踪来自 JPA,但这是因为过滤器库将日期转换为一种奇怪的格式

Parameter value [Wed Jan 18 00:00:00 UTC 2023] did not match expected type [java.time.LocalDateTime (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [Wed Jan 18 00:00:00 UTC 2023] did not match expected type [java.time.LocalDateTime (n/a)]

过滤器表达式似乎将参数强制转换为 Date 类型,但 SQL 列是 DateTime。

当我在线查看时,有一些使用本机查询的解决方案,由于我使用的自定义过滤器对象,这些方法在这里不起作用(我可以通过构建 JPA 表达式来查询多个字段,并且唯一不起作用的过滤器是LocalDateTime)。

编辑:更多细节

在 SQL 中,列类型是 DateTime 并且没有为休眠中的列定义指定任何特殊内容。

完整的堆栈跟踪

Caused by: java.lang.IllegalArgumentException: Parameter value [Wed Jan 18 00:00:00 UTC 2023] did not match expected type [java.time.LocalDateTime (n/a)]
    at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:54) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
    at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:27) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
    at org.hibernate.query.internal.QueryParameterBindingImpl.validate(QueryParameterBindingImpl.java:90) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
    at org.hibernate.query.internal.QueryParameterBindingImpl.setBindValue(QueryParameterBindingImpl.java:55) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
    at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:501) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
    at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:122) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
    at org.hibernate.query.criteria.internal.compile.CriteriaCompiler$1$1.bind(CriteriaCompiler.java:140) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
    at org.hibernate.query.criteria.internal.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:364) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
    at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:170) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:774) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:114) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311) ~[spring-orm-5.3.18.jar:5.3.18]
    at jdk.proxy2/jdk.proxy2.$Proxy207.createQuery(Unknown Source) ~[na:na]
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:801) ~[spring-data-jpa-2.6.4.jar:2.6.4]
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:779) ~[spring-data-jpa-2.6.4.jar:2.6.4]
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:517) ~[spring-data-jpa-2.6.4.jar:2.6.4]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:529) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:639) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:163) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18]
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.6.4.jar:2.6.4]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18]
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.18.jar:5.3.18]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.18.jar:5.3.18]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.18.jar:5.3.18]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.18.jar:5.3.18]
    ... 53 common frames omitted

编辑2:

问题在于我的 graphql 库如何从 FilterExpression.newFilterExpressionBuilder().args(env.getArguments()).build() 构建日期时间过滤器。我可以通过省略 DateTime 过滤器并在之后自己添加规范来稍微绕过一些事情,但理想情况下我可以让事情与过滤器表达式构建器一起工作。

【问题讨论】:

  • UTC——为什么参数有时间偏移(在这种情况下是通用时钟)? LocalDateTime 不能接受时间偏移或时区。您传递的参数值似乎是时间戳有时区或类似的。摆脱时区。
  • 看起来在 java.util.Date 对象上调用了 toString,它以默认的本地/时区/格式打印日期。这并不意味着指定了 UTC 时区,只是该值表示 UTC 中的 1 月 18 日午夜。这是一个 Java 异常,所以问题在于您传递给查询的内容 - 您的参数不是 LocalDateTime,因此请检查您的方法签名和值,因为您可能需要转换它,因为我不认为这是将任何内容更改为 Date 对象的规范。你是如何以及从哪里得到这个例外的? (即显示堆栈跟踪)
  • 我通过 graphql playground 传递值,它只接受某些输入或无限期挂起
  • 我传入的输入是 2023-01-18T00:00,它似乎正确解析为 LocalDateTime。我会将完整的堆栈跟踪添加到帖子中
  • 当我转换为 LocalDateTime 时,我也可以使用 dateFormatter,但这并没有真正改变任何东西,因为我总是能够转换为 LocalDateTime 对象。尝试在 JPA 中执行时出现问题

标签: java sql spring jpa graphql


【解决方案1】:

问题最终成为过滤器库的这一部分。我不得不 fork 存储库,删除代码块,然后发布我自己的库版本:https://github.com/intuit/graphql-filter-java/issues/29

希望将来可以为其他人更正式地修复它:)

【讨论】:

    猜你喜欢
    • 2016-12-27
    • 2023-03-29
    • 2018-12-25
    • 2018-08-29
    • 2022-11-30
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    相关资源
    最近更新 更多