我在 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
时有效。
不过,您的本机查询将需要匹配的大小写。
我正在向数据库发送一个非常简单的查询,但出现错误。感觉就像我错过了一些非常简单的东西。我想它不允许我创建它,因为词序是 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
时有效。
不过,您的本机查询将需要匹配的大小写。