【问题标题】:SQL Query error in JSF, JPA applicationJSF、JPA 应用程序中的 SQL 查询错误
【发布时间】:2013-10-25 02:41:22
【问题描述】:

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

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;
      }
   } 

这是错误:javax.ejb.EJBException

在我发现的踪迹中:

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

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


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

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


应@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 + " ]";
   }

}

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

   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();
   }
}

【问题讨论】:

  • 不要删除旧问题,否则试图解决该问题的答案将失效。只需将相关信息添加到特定问题即可。
  • @LuiggiMendoza 是真的,谢谢你的建议

标签: java jpa


【解决方案1】:

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

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

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

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

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

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

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

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

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

所以JPQL查询应该是

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

【讨论】:

  • 刚刚编辑了我的问题,并将代码更改为您的建议。我现在遇到了一个新错误。
  • @JeanCarlosSuárezMarranzini 是 Product 一个实体吗?添加Product
  • 最好使用命名参数添加参数,而不是像这样天真地添加它们的值。请注意,这些泄漏会使您的应用程序容易受到 SQL 注入攻击。
  • @JeanCarlosSuárezMarranzini JPA 将在 JPA 无法找到您的实体类时抛出 "Unknown abstract schema type" 错误
  • @JeanCarlosSuárezMarranzini 可能使用了区分大小写的解析器。尝试SELECT p FROM Product p WHERE p.category=' ... 而不是大写
猜你喜欢
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多