带有 CURRENT_DATE - 1 的 JPQL 查询不起作用

Posted

技术标签:

【中文标题】带有 CURRENT_DATE - 1 的 JPQL 查询不起作用【英文标题】:JPQL query with CURRENT_DATE - 1 does not work 【发布时间】:2018-07-28 17:50:29 【问题描述】:

我是JPA2.0Spring Data JPA 的新手,我正在尝试获取详细信息where createdDt > Sysdate and createdDt > sysdate-1。我不确定是否可以使用 CURRENT_DATE-1 函数实现 sysdate-1,它不起作用。

以下选项的任何帮助都不起作用?我也试过YESTERDAY,也失败了。

这里我不打算使用 PersistanceContext 和实体管理器查询来开发。

@Query("SELECT e FROM CustMstr e WHERE e.crteDt < CURRENT_DATE AND (DAYS(e.crteDt) > DAYS(CURRENT_DATE) - 1) AND e.accActive ='Y'")
List<CustMstr> findByEmailAndAcc();

另一种方式

@Query("SELECT e FROM CustMstr e WHERE e.crteDt < CURRENT_DATE AND (DAYS(e.crteDt) > CURRENT_DATE - 1) AND e.accActive ='Y'")
List<CustMstr> findByEmailAndAcc();

以下错误

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'exampleClient': Unsatisfied dependency expressed through field 'CustMstrRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CustMstrRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.XX.XX.repository.CustMstrRepository.findByEmailAndAcc()!
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:581)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:367)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1340)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
    at com.XX.XX.app.ExampleMain.main(ExampleMain.java:10)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CustMstrRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.XX.XX.repository.CustMstrRepository.findByEmailAndAcc()!
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1704)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:583)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1133)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1060)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:578)
    ... 15 more
Caused by: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Syntax error parsing [SELECT e FROM CustMstr e WHERE e.crteDt < CURRENT_DATE AND (DAYS(e.crteDt) > DAYS(CURRENT_DATE) - 1) AND e.acc_active ='Y']. 
[62, 103] The right expression is not a valid expression.
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1616)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350)
    at com.sun.proxy.$Proxy22.createQuery(Unknown Source)
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:87)
    ... 54 more

【问题讨论】:

【参考方案1】:

JPA 将 CURRENT_DATE / CURRENT_TIME / CURRENT_TIMESTAMP 定义为引用当前日期/时间的可移植方式。

此外,一些实现(不是全部!)支持功能,如 year / month / day / hour / minute / second

在您的代码中,您使用days。您可以将其替换为day。但它是一个提取月份中的一天,不确定它是你想要的。

如果你想引用“昨天”,你可以尝试使用CURRENT_DATE-1,但这不是必须的(有些数据库可以,其他的不行)。

你可以试试:

@Query("SELECT e FROM CustMstr e WHERE e.crteDt between CURRENT_DATE-1 AND  CURRENT_DATE AND e.accActive ='Y'")
List<CustMstr> findByEmailAndAcc();

但也许您需要在 java 端进行管理:

在存储库方面:

@Query("SELECT e FROM CustMstr e WHERE e.crteDt between :start and :end AND e.accActive ='Y'")
List<CustMstr> findByEmailAndAcc(Date start, Date end);

在服务方面:

List<CustMstr> findByEmailAndAcc()
    Date start=new Date();
    Date end=new Date(date.getTime()-(24*3600));
    return repository.findByEmailAndAcc(start, end);

【讨论】:

谢谢..检查..如果我只需要查询 where created > sysdate - 60 怎么办? 刚尝试创建> CURRENT_DATE-60 正如我所指出的,它可能取决于您使用的数据库和 jpa 适配器。例如,(current_date-60)可以在 postgresql 上使用 hibernate,即使我永远不会使用它。我更喜欢第二个选项 I Show 在 java 中创建日期。这样你就有 1 个存储库 findByDate(Date starting);并且您可以关联许多服务(findLastDay、findLastWeek ...)

以上是关于带有 CURRENT_DATE - 1 的 JPQL 查询不起作用的主要内容,如果未能解决你的问题,请参考以下文章

redshift sql current_date get_date() 性能问题

第三十五章 SQL函数 CURRENT_DATE

将 current_date 转换为相对日期和静态时间

BigQuery 结果中的 CURRENT_DATE 到昨天的日期

hive 函数 current_date()

如何解释这个涉及 current_date 的插入语句的行为