【问题标题】:Spring JPA @Query JPQL fails with "Unexpected token: DATE"Spring JPA @Query JPQL 因“意外令牌:日期”而失败
【发布时间】:2021-12-03 02:25:00
【问题描述】:

我正在使用 Spring Data JPA,我想查询我的结果并过滤它们。在 SQL 中,我会像这样编写查询(针对 DB2 数据库):

SELECT * FROM CAR 
WHERE ACCIDENT_YEAR IS NULL 
  OR BUY_YEAR >= CURRENT_DATE 
ORDER BY CAR_NUMBER

对于 Spring JPA,我正在尝试使用 @Query 注释和 JPQL 来做同样的事情:

@Repository
public interface CarRepository extends JpaRepository<CarEntity, Integer> {
    
    @Query("SELECT c FROM CAR c WHERE c.EXPIRY_DATE IS NULL OR c.EXPIRY_DATE >= CURRENT DATE")
    List<CarEntity> findAllNonExpiredCars(Sort sort);
}

,然后我可以像这样调用这个方法:

carRepository.findAllNonExpiredCars(Sort.by("CAR_NUMBER"));

但是,当我执行 Maven > 安装时,出现以下错误:

NoViableAltException:意外令牌:DATE

,和

org.hibernate.hql.internal.ast.QuerySyntaxException:意外令牌:DATE 靠近第 1 行第 84 列 [SELECT c FROM CAR c WHERE c.EXPIRY_DATE IS NULL OR c.EXPIRY_DATE >= CURRENT DATE]

上面的查询怎么写?

【问题讨论】:

  • 试试CURRENT_DATE
  • @GeorgeLvov 谢谢,这消除了上面的错误,但现在我得到 java.lang.IllegalArgumentException: Validation failed for query for public abstract java.util.List CarRepository.findAllNonExpiredCars(org .springframework.data.domain.Sort)!
  • 把你的实体名而不是表名放在查询中,所以CarEntity而不是CAR
  • 我明白了:)。因此,在@Query 中,我应该引用实体及其字段,而不是数据库表及其字段。一旦我将CAR(数据库表)替换为实体CarEntity,并将EXPIRY_DATE(数据库字段)替换为carEntity.expiryDate,它现在就可以工作了。谢谢你。您能否将您的 cmets 放入答案中,以便我接受您的答案。非常感谢@GeorgeLvov

标签: java spring-boot spring-data-jpa


【解决方案1】:

如果您想使用 @Query 注释定义查询,您可以使用 JPQL-query(查询定义默认使用它)或原生 SQL(使用 nativeQuery = true)。 SQL 适用于关系数据库表、记录和字段,而 JPQL 适用于 Java 类和对象。

在您的情况下,您混合了两种选择。你可以这样做:

JPQL:

public interface CarRepository extends JpaRepository<CarEntity, Integer> {
    
    @Query("SELECT c FROM CarEntity c WHERE c.expiryDate IS NULL OR c.expiryDate >= CURRENT_DATE")
    List<CarEntity> findAllNonExpiredCars(Sort sort);
}

原生 SQL:

public interface CarRepository extends JpaRepository<CarEntity, Integer> {
    
@Query("SELECT * FROM schema_name.CAR WHERE EXPIRY_DATE IS NULL OR EXPIRY_DATE >= CURRENT_DATE ORDER BY some_field_name",
        nativeQuery = true)
List<CarEntity> findAllNonExpiredCars();
}

看看这些链接:

Spring Data JPA - Reference Documentation. Query Methods

Spring Data JPA @Query. Baeldung

Types of JPA Queries. Baeldung

【讨论】:

  • nativeQuery 唯一的问题是它不支持排序。最初我以为我会使用它。我还有另一个问题:在 JPL 中,我们必须为存储库方法使用某些命名约定。即使我们使用 @Query 注释,这是否适用?再次感谢,你的回答救了我~
  • 你说得对,使用原生 SQL 查询无法定义排序。您可以为您的方法选择任何名称,以免意外覆盖 JpaRepository 所需的方法。
  • 非常感谢@GeorgeLvov
猜你喜欢
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 2015-02-11
  • 2021-02-27
  • 2019-01-30
  • 2015-08-30
  • 1970-01-01
  • 2011-07-15
相关资源
最近更新 更多