Java JSF、JPA 应用程序中的 SQL 查询错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19412642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 16:56:40  来源:igfitidea点击:

SQL Query error in JSF, JPA application

javajpa

提问by Jean Carlos Suárez Marranzini

I have a problem with a query in my application. This is the query method doing the query:

我的应用程序中的查询有问题。这是执行查询的查询方法:

public List<Product> obtainProductListByCategory(String category)
   {
      Query query = em.createQuery("SELECT p FROM PRODUCT p WHERE CATEGORY='" + category + "'");
      List<Product> ret = query.getResultList();

      if (ret == null)
      {
         return new ArrayList<Product>();
      }
      else
      {
         return ret;
      }
   } 

And this is the error: javax.ejb.EJBException

这是错误: javax.ejb.EJBException

And in the trace I found:

在跟踪中我发现:

Caused by: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: Exception Description: Syntax error parsing [SELECT * FROM PRODUCT WHERE CATEGORY='Humano']. [22, 22] A select statement must have a FROM clause. [7, 7] The left expression is missing from the arithmetic expression. [9, 22] The right expression is not an arithmetic expression

引起:java.lang.IllegalArgumentException:在EntityManager中创建查询时发生异常:异常描述:语法错误解析[SELECT * FROM PRODUCT WHERE CATEGORY='Humano']。[22, 22] select 语句必须有一个 FROM 子句。[7, 7] 算术表达式中缺少左表达式。[9, 22] 正确的表达式不是算术表达式

Any ideas? My objective is to refresh a JSF datatable in my webpage.

有任何想法吗?我的目标是刷新我网页中的 JSF 数据表。



Edited my code based on @Ilya's answer, and now I got this exception

根据@Ilya 的回答编辑了我的代码,现在我得到了这个异常

Caused by: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: Exception Description: Problem compiling [SELECT p FROM PRODUCT p WHERE CATEGORY='Humano']. [14, 21] The abstract schema type 'PRODUCT' is unknown. [30, 38] The identification variable 'CATEGORY' is not defined in the FROM clause.

引起:java.lang.IllegalArgumentException:在 EntityManager 中创建查询时发生异常:异常描述:编译问题 [SELECT p FROM PRODUCT p WHERE CATEGORY='Humano']。[14, 21] 抽象模式类型“产品”是未知的。[30, 38] 标识变量“CATEGORY”未在 FROM 子句中定义。



As requested by @Ilya, I post my Productclass: EDIT: Added @Table to the annotations.

根据@Ilya 的要求,我发布了我的Product课程:编辑:在注释中添加了@Table。

package model;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;


@Table
@Entity
public class Product implements Serializable, IProduct
{
   private static final long serialVersionUID = 1L;
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Id
   private String name;
   private int stock;
   private float price;
   private String category;
   private String description;

  @Override 
  public String getDescription() {
        return description;
    }


  public void setDescription(String description) {
        this.description = description;
    }


   public Product()
   {
   }


   public Product(String name, int stock, float price, String category, String description)
   {
      this.name = name;
      this.stock = stock;
      this.price = price;
      this.category = category;
      this.description = description;
   }





   @Override
   public String getName()
   {
      return name;
   }


   public void setName(String name)
   {
      this.name = name;
   }


   @Override
   public float getPrice()
   {
      return price;
   }


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


   @Override
   public int getStock()
   {
      return stock;
   }


   public void setStock(int stock)
   {
      this.stock = stock;
   }


   @Override
   public int hashCode()
   {
      return name.hashCode();
   }


   @Override
   public boolean equals(Object object)
   {
      if (!(object instanceof Product))
      {
         return false;
      }
      Product other = (Product) object;
      if (name.equals(other.getName()))
      {
         return true;
      }
      return false;
   }

   @Override
   public String getCategory()
   {
      return category;
   }

   @Override
   public String toString()
   {
      return "Marketv2.model.Product[ name=" + name + " ]";
   }

}

Thanks for the help so far. Here I post another query in my application, which is working properly:

感谢你目前的帮助。在这里,我在我的应用程序中发布了另一个查询,该查询正常工作:

   public void removeProduct(Product g)
   {
      Query q = em.createQuery("SELECT x FROM BasketItem x WHERE x.product.name = '" + g.getName() + "'");
      List<BasketItem> bItems = q.getResultList();
      for (BasketItem i : bItems)
      {
         em.remove(i);
      }

      q = em.createQuery("DELETE FROM Product x WHERE x.name = '" + g.getName() + "'");
      q.executeUpdate();
   }
}

采纳答案by Ilya

1) You should specify alias for tables in FROMclause, and SELECTclause should contains alias
Productshould be an entity

1)你应该在FROM子句中为表指定别名,SELECT子句应该包含别名
Product应该是一个实体

em.createQuery("SELECT p FROM Product p WHERE p.category='" + category + "'");   

If PRODUCTisn't an entity, you should create nativeQuery

如果PRODUCT不是实体,则应创建nativeQuery

em.createNativeQuery("SELECT p FROM PRODUCT p WHERE p.CATEGORY='" + category + "'");  

EntityManager::createQueryis for JPQL (Java Persistence query language)
EntityManager::createNativeQueryis for SQL

EntityManager::createQuery适用于 JPQL(Java 持久性查询语言)
EntityManager::createNativeQuery适用于 SQL

2) JPA throws the "Unknown abstract schema type"error when JPA fails to locate your entity class
Also add entity to persistence.xml

2)JPA"Unknown abstract schema type"无法定位您的实体类时,JPA 抛出错误
并将实体添加到persistence.xml

 <persistence-unit ...>
        <class>com.package.Product</class>  

3) Add @Tableannotation to your @Entity
4) As I see in documentation, JPQL is case-sensitive.

3)@Table向您的@Entity
4 ) 添加注释,正如我在文档中看到的,JPQL 区分大小写。

With the exception of names of Java classes and properties, queries are case-insensitive. So SeLeCT is the same as sELEct is the same as SELECT, but org.hibernate.eg.FOO and org.hibernate.eg.Foo are different, as are foo.barSet and foo.BARSET.

除了 Java 类和属性的名称之外,查询不区分大小写。所以SeLeCT和sELEct一样,SELECT和SELECT一样,但是org.hibernate.eg.FOO和org.hibernate.eg.Foo是不同的,foo.barSet和foo.BARSET也是不同的。

So JPQL query should be

所以JPQL查询应该是

SELECT p FROM Product p WHERE p.category = '...