2013-10-16 60 views
4

我的應用程序中的查詢有問題。這是查詢的方法去查詢:JSF,JPA應用程序中的SQL查詢錯誤

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

而且在跟蹤,我發現:

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

任何想法?我的目標是在我的網頁中刷新JSF數據表。


編輯根據我的代碼上@伊利亞的回答,現在我得到這個例外

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.


按照要求通過@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(); 
    } 
} 
+0

請**不要**刪除舊的問題,否則,那些試圖解決這一問題變得無效答案。只需將相關信息添加到特定問題即可。 –

+0

@LuiggiMendoza這是真的,謝謝你的建議 –

回答

12

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時JPA無法找到實體類
同時添加實體persistence.xml中

2)JPA拋出"Unknown abstract schema type"錯誤

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

3)添加註釋@Table@Entity
4)正如我在documentation看到,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.

所以JPQL查詢應該是

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

剛編輯我的問題,並將代碼更改爲你的建議。我現在得到一個新的錯誤。 –

+0

@JeanCarlosSuárezMarranzini是'Product'的一個實體?添加'Product'類 – Ilya

+1

最好使用命名參數添加參數,而不是像這樣天真地添加它們的值。請注意,這些泄漏使您的應用程序面臨SQL注入攻擊。當JPA無法找到實體類 –