Запрос JPQL с CURRENT_DATE - 1 не работает

Я новичок в JPA2.0 и Spring Data JPA, где я пытаюсь получить подробности where createdDt > Sysdate and createdDt > sysdate-1. Я не уверен, что sysdate-1 можно получить с помощью функции CURRENT_DATE-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

person Jeff Cook    schedule 28.07.2018    source источник


Ответы (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);
}
person wargre    schedule 28.07.2018
comment
Спасибо.. проверю.. что, если мне нужен только запрос, где создан › sysdate-60? - person Jeff Cook; 28.07.2018
comment
просто попробуйте создать › CURRENT_DATE-60 - person wargre; 28.07.2018
comment
Как я уже отмечал, это может зависеть от используемой вами БД и адаптера jpa. Например, (current_date-60) нормально работает со спящим режимом в postgresql, даже если я, например, никогда не буду его использовать. Я бы предпочел второй вариант. Я показываю создание даты в java. Таким образом, у вас есть 1 репозиторий findByDate (дата начала); и у вас может быть много связанных сервисов (findLastDay, findLastWeek...) - person wargre; 29.07.2018