【问题标题】:JpaRepository is creating a wrong queryJpaRepository 正在创建错误的查询
【发布时间】:2022-01-23 16:32:47
【问题描述】:

我有以下问题

package gt.com.anibal.dao;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import gt.com.anibal.model.Order;

@Repository
public interface OrderDao extends JpaRepository<Order, Long>{
    
    //@Query("SELECT o FROM Order o")
    @Query(value = "SELECT * FROM Order o WHERE o.price = ?1", nativeQuery = true) //native query
    public List<Order> findOrder(double price);
}

这就是错误

    SELECT
        * 
    FROM
        
    Order o WHERE
        o.price = ?
10:13 TRACE 13460 --- [nio-9091-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [DOUBLE] - [25.0]
10:13  WARN 13460 --- [nio-9091-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1064, SQLState: 42000
10:13 ERROR 13460 --- [nio-9091-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper   : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Order o WHERE o.price = 25.0' at line 1
10:13 ERROR 13460 --- [nio-9091-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause

java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Order o WHERE o.price = 25.0' at line 1

如果我在 MySQL 上运行查询,它可以正常工作

 SELECT
        * 
    FROM

    test.Order o WHERE
        o.price = 25.0

但我认为 JpaRepository 它在 from 和 where 之间创建了一个空格,当我在另一个实体中使用 JpaRepository 时,它在我的控制台中的查询不同

package gt.com.anibal.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import gt.com.anibal.model.Persona;

@Repository
public interface PersonaDao extends JpaRepository<Persona, Long> {

}

这是结果,我没有看到 from 和下一行之间的空格,我不知道这是问题还是另一个问题。

    select
        persona0_.id_persona as id_perso1_3_,
        persona0_.apellido as apellido2_3_,
        persona0_.email as email3_3_,
        persona0_.nombre as nombre4_3_,
        persona0_.telefono as telefono5_3_ 
    from
        persona persona0_

这是我的实体

package gt.com.anibal.model;

import java.sql.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table( name = "order" )
public class Order {

    @Id
    @Column(name = "idorder", columnDefinition = "int")
    private Long idOrder;

    @Column( name = "description")
    private String descriptions;
    
    @OneToMany(mappedBy = "order")
    private Set<Customer> customer = new HashSet<>();

    @Column( name = "date")
    private Date date;
    
    @Column( name = "price", precision = 10, scale = 2)
    private double price;

    public Long getIdOrder() {
        return idOrder;
    }

    public void setIdOrder(Long idOrder) {
        this.idOrder = idOrder;
    }

    public String getDescriptions() {
        return descriptions;
    }

    public void setDescriptions(String descriptions) {
        this.descriptions = descriptions;
    }

    public Set<Customer> getCustomer() {
        return customer;
    }

    public void setCustomer(Set<Customer> customer) {
        this.customer = customer;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
    
    
    

}

这是我在 MySQL 上的表

CREATE TABLE `order` (
  `idOrder` int NOT NULL,
  `description` varchar(45) NOT NULL,
  `idCustomer` varchar(45) NOT NULL,
  `date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `price` decimal(10,2) NOT NULL DEFAULT '0.00',
  PRIMARY KEY (`idOrder`),
  KEY `fk_order_customer_idx` (`idOrder`),
  CONSTRAINT `fk_order_customer` FOREIGN KEY (`idOrder`) REFERENCES `customer` (`idCustomer`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

【问题讨论】:

  • 您的 Order 表是否位于不同的架构中?我可以在您的手动查询示例中看到 test.Order,但在其他查询或您的代码中看不到。
  • 我的所有实体都在相同的模式、角色和顺序中,我正在尝试一些查询来练习
  • Order 是 SQL 中的保留关键字,您必须在查询“select * from `order`...”(但您不需要本机)和实体@Table(name = "`order`")
  • 感谢您的建议,这很好用,我将 MySQL 上的表名称和我的实体名称更改为其他名称

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


【解决方案1】:

对于这种简单的查询,我建议使用JPA Query Methods

您的方法应命名如下:

@Repository
public interface OrderDao extends JpaRepository<Order, Long>{
    List<Order> findByPrice(double price);
}

这是一个更干净的代码。

如果您想在更多情况下使用本机查询,则应将“?1”替换为方法变量名称,并以分号为前缀,例如“:price”。

【讨论】:

  • 我试过用那种方式,但我有同样的问题,SQL语法,
  • 我现在可以看到问题所在。也许您的表名是 order,而不是 Order,尝试与您的表名匹配,您介意将您的 Entity 对象和您的 DDL 分享给我们吗?也许我们可以更好地排除故障。
  • 我编辑了我的问题,并添加了我的实体和我的 DDL
【解决方案2】:

@rortegat 的建议是编写简单查询的好方法[至少对我而言]。 现在,在您的查询中:

@Query(value = "SELECT * FROM Order o WHERE o.price = ?1", nativeQuery = true)

这里* 表示所有列的行/记录,但您的方法返回不兼容的List&lt;Order&gt;。 相反,像这样更改您的查询: @Query(value = "SELECT o FROM Order o WHERE o.price = ?1", nativeQuery = true)

这里,SELECT o FROM Order o 这部分意味着您通过别名 o 从查询中返回 Order 实例。

【讨论】:

  • 我试过用这种方式,如果你看到了,我已经评论了那行,当我尝试时
  • 那我看不出有什么问题。您能否在上面的问题中查看@Andriy Slobodyanyk 评论?只需重命名表格并尝试使用它。应该管用。显然,使用o 而不是* 符号。
【解决方案3】:

当您使用 nativeQuery = true 时,它​​将被解释为您可以直接在 MySQL 中执行的标准 SQL。如果您删除 nativeQuery = true,@Query 将解释为 JPQL。你想用哪一个?

试试这个:

Query(value = "SELECT * FROM Order WHERE price = ?1", nativeQuery = true) //原生查询

nativeQuery 为真时,Order 必须是表名,price 必须是列名。

或者,试试这个使用 jpql:

Query(value = "SELECT o FROM Order o WHERE o.price = ?1")

【讨论】:

  • 我尝试不使用nativeQuery,我使用@Query(value = "SELECT o FROM Order o WHERE o.price = ?1"),但我遇到了同样的问题
猜你喜欢
  • 2016-06-25
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多