我在 jpa 中的本机查询有什么问题?

What is wrong with my native query in jpa?

我正在向数据库发送一个非常简单的查询,但出现错误。感觉就像我错过了一些非常简单的东西。我想它不允许我创建它,因为词序是 h2 数据库上的关键字,所以我将它放在 table 注释中的引号中。

   @Query(value = "select * from `ORDER` o where o.basket_id= :basketId ", nativeQuery = true)
    Optional<Order> getOrderByBasketId(Long basketId);
@Entity
@Getter
@Setter
@Table(name = "`ORDER`")
public class Order extends BaseExtendedModel{
            private BigDecimal price;
            @Enumerated(EnumType.STRING)
            private OrderStatus orderStatus;
            @OneToOne
            private Customer customer;
            @OneToOne(cascade = CascadeType.MERGE)
            private Basket basket;
            @OneToOne(cascade = CascadeType.ALL, mappedBy = "order")
            private OrderAddress orderAddress;
}
{
    "errorMessage": "could not prepare statement; SQL [select * from `ORDER` o where o.basket_id= ? ]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement"
}

您需要使用索引参数

@Query(value = "select * from `ORDER` o where o.basket_id= ?1", nativeQuery = true)
Optional<Order> getOrderByBasketId(Long basketId);

或命名参数

@Query(value = "select * from `ORDER` o where o.basket_id= :basketId", nativeQuery = true)
Optional<Order> getOrderByBasketId(@Param("basketId") Long basketId);

当您查看日志时,问题更容易确定。您会看到这样的条目:

org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "ORDER" not found; SQL statement:

那么让我们看看执行了哪些SQL语句。所以我们将以下内容添加到 application.properties

spring.jpa.show-sql=true

假设您让 spring 引导创建您的 tables,您将看到以下内容:

Hibernate: drop table if exists "order" CASCADE Hibernate: create table "order" ...

当我们点击存储库方法时,我们看到

select * from `ORDER` o where o.name= ? [42102-200]

那么为什么它创建了小写的 table,即使我们指定了 @Table(name = "`ORDER`")

spring.jpa.hibernate.naming.physical-strategy 的默认值是 org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

  • 用下划线替换点
  • 将 CamelCase 更改为 snake_case
  • lower-cases table 个名字。

但我们希望它采用我们在 @Table 中使用的名称。这在将 属性 设置为 spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl 时有效。

不过,您的本机查询将需要匹配的大小写。